summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2002-07-01 23:24:08 (UTC)
committer llornkcor <llornkcor>2002-07-01 23:24:08 (UTC)
commit59222a752fa4c8a1e8c2a00ee2f9e22855f12bb2 (patch) (unidiff)
treef148d4858859dac3b413e675c760acfdab24b8e6
parentc08be8ae22dcc1bfb83cfdec807149b161d770f5 (diff)
downloadopie-59222a752fa4c8a1e8c2a00ee2f9e22855f12bb2.zip
opie-59222a752fa4c8a1e8c2a00ee2f9e22855f12bb2.tar.gz
opie-59222a752fa4c8a1e8c2a00ee2f9e22855f12bb2.tar.bz2
initial
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/Aportis.cpp291
-rw-r--r--noncore/apps/opie-reader/Aportis.h86
-rw-r--r--noncore/apps/opie-reader/BuffDoc.cpp126
-rw-r--r--noncore/apps/opie-reader/BuffDoc.h138
-rw-r--r--noncore/apps/opie-reader/CBuffer.cpp35
-rw-r--r--noncore/apps/opie-reader/CBuffer.h45
-rw-r--r--noncore/apps/opie-reader/CEncoding.cpp150
-rw-r--r--noncore/apps/opie-reader/CEncoding.h53
-rw-r--r--noncore/apps/opie-reader/CExpander.h145
-rw-r--r--noncore/apps/opie-reader/CFilter.h354
-rw-r--r--noncore/apps/opie-reader/QTReader.cpp1034
-rw-r--r--noncore/apps/opie-reader/QTReader.h217
-rw-r--r--noncore/apps/opie-reader/QTReaderApp.cpp1433
-rw-r--r--noncore/apps/opie-reader/QTReaderApp.h206
-rw-r--r--noncore/apps/opie-reader/QtrListView.cpp24
-rw-r--r--noncore/apps/opie-reader/QtrListView.h20
-rw-r--r--noncore/apps/opie-reader/Queue.h21
-rw-r--r--noncore/apps/opie-reader/README162
-rw-r--r--noncore/apps/opie-reader/Text.h28
-rw-r--r--noncore/apps/opie-reader/ZText.h35
-rw-r--r--noncore/apps/opie-reader/arith.h43
-rw-r--r--noncore/apps/opie-reader/arith_d.cpp94
-rw-r--r--noncore/apps/opie-reader/cbkmkselector.h41
-rw-r--r--noncore/apps/opie-reader/config.h21
-rw-r--r--noncore/apps/opie-reader/fileBrowser.cpp185
-rw-r--r--noncore/apps/opie-reader/fileBrowser.h70
-rw-r--r--noncore/apps/opie-reader/infowin.cpp41
-rw-r--r--noncore/apps/opie-reader/infowin.h52
-rw-r--r--noncore/apps/opie-reader/main.cpp38
-rw-r--r--noncore/apps/opie-reader/my_list.h172
-rw-r--r--noncore/apps/opie-reader/opie-reader.control9
-rw-r--r--noncore/apps/opie-reader/opie-reader.pro48
-rw-r--r--noncore/apps/opie-reader/pdb.cpp57
-rw-r--r--noncore/apps/opie-reader/pdb.h90
-rw-r--r--noncore/apps/opie-reader/ppm.cpp756
-rw-r--r--noncore/apps/opie-reader/ppm.h179
-rw-r--r--noncore/apps/opie-reader/ppm_expander.cpp108
-rw-r--r--noncore/apps/opie-reader/ppm_expander.h46
-rwxr-xr-xnoncore/apps/opie-reader/update.sh11
-rw-r--r--noncore/apps/opie-reader/ustring.h71
-rw-r--r--noncore/apps/opie-reader/utypes.h14
-rw-r--r--noncore/apps/opie-reader/version.h3
-rw-r--r--noncore/apps/opie-reader/ztxt.cpp159
-rw-r--r--noncore/apps/opie-reader/ztxt.h102
44 files changed, 7013 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/Aportis.cpp b/noncore/apps/opie-reader/Aportis.cpp
new file mode 100644
index 0000000..595b385
--- a/dev/null
+++ b/noncore/apps/opie-reader/Aportis.cpp
@@ -0,0 +1,291 @@
1#include <stdio.h>
2#include <string.h>
3#include "Aportis.h"
4
5Aportis::Aportis() { /*printf("constructing:%x\n",fin);*/ }
6
7CList<Bkmk>* Aportis::getbkmklist()
8{
9 if (bCompressed != 4) return NULL;
10 CList<Bkmk>* t = new CList<Bkmk>;
11 size_t cur = ftell(fin);
12 for (int i = 0; i < nRecs2; i++)
13 {
14 DWORD dwPos;
15 fseek(fin, 0x56 + 8*i, SEEK_SET);
16 fread(&dwPos, 4, 1, fin);
17 dwPos = SwapLong(dwPos);
18 fseek(fin,dwPos,SEEK_SET);
19 unsigned char ch;
20 fread(&ch,1,1,fin);
21 if (ch != 241)
22 {
23 char name[17];
24 name[16] = '\0';
25 fseek(fin,dwPos,SEEK_SET);
26 fread(name,1,16,fin);
27 unsigned long lcn;
28 fread(&lcn,sizeof(lcn),1,fin);
29 lcn = SwapLong(lcn);
30#ifdef _UNICODE
31 tchar tname[17];
32 memset(tname, 0, sizeof(tname));
33 for (int i = 0; name[i] != 0; i++)
34 {
35 tname[i] = name[i];
36 }
37 t->push_back(Bkmk(tname,lcn));
38#else
39 t->push_back(Bkmk(name,lcn));
40#endif
41 }
42 }
43 fseek(fin, cur, SEEK_SET);
44 return t;
45}
46
47int Aportis::openfile(const char *src)
48{
49
50 // printf("In openfile\n");
51 int ret = 0;
52
53 if (!Cpdb::openfile(src)) return -1;
54
55 if (head.creator != 0x64414552 // 'dAER'
56 || head.type != 0x74584554) // 'tXET')
57 {
58 return -2;
59 }
60
61 gotorecordnumber(0);
62 tDocRecord0 hdr0;
63 fread(&hdr0, sizeof(hdr0), 1, fin);
64 bCompressed = SwapWord(hdr0.wVersion);
65 if (bCompressed!=1 && bCompressed!=2 && bCompressed != 4) {
66 ret = bCompressed;
67 bCompressed = 2;
68 }
69
70 fseek(fin,0,SEEK_END);
71 dwLen = ftell(fin);
72 nRecs2 = nRecs = SwapWord(head.recordList.numRecords) - 1;
73
74 switch (bCompressed)
75 {
76 case 4:
77 {
78 dwTLen = 0;
79 int i;
80 for (i = 0; i < nRecs; i++)
81 {
82 unsigned int bs = GetBS(i);
83 if (bs == 0) break;
84 else dwTLen += bs;
85 }
86 nRecs = i;
87 BlockSize = 0;
88 }
89 break;
90 case 1:
91 case 2:
92 default:
93 dwTLen = SwapLong(hdr0.dwStoryLen);
94 BlockSize = SwapWord(hdr0.wRecSize);
95 if (BlockSize == 0)
96 {
97 BlockSize = 4096;
98 printf("WARNING: Blocksize not set in source file\n");
99 }
100 }
101
102
103 // this is the main record buffer
104 // it knows how to stretch to accomodate the decompress
105 currentrec = 0;
106 cbptr = 0;
107 outptr = 0;
108 refreshbuffer();
109 return ret;
110}
111
112int Aportis::getch()
113{
114 if (bCompressed == 1)
115 {
116 if ((dwRecLen == 0) && !refreshbuffer()) return EOF;
117 else
118 {
119 int c = getc(fin);
120 dwRecLen--;
121 currentpos++;
122 return c;
123 }
124 }
125 if (outptr != cbptr)
126 {
127 currentpos++;
128 return (circbuf[outptr = (outptr + 1) % 2048]);
129 }
130 if ((dwRecLen == 0) && !refreshbuffer()) return EOF;
131 currentpos++;
132 unsigned int c;
133
134 // take a char from the input buffer
135 c = getc(fin);
136 dwRecLen--;
137 // separate the char into zones: 0, 1...8, 9...0x7F, 0x80...0xBF, 0xC0...0xFF
138
139 // codes 1...8 mean copy that many chars; for accented chars & binary
140 if (c == 0)
141 {
142 circbuf[outptr = cbptr = (cbptr+1)%2048] = c;
143 return c;
144 }
145 else if (c >= 0x09 && c <= 0x7F)
146 {
147 circbuf[outptr = cbptr = (cbptr+1)%2048] = c;
148 return c;
149 }
150 else if (c >= 0x01 && c <= 0x08)
151 {
152 dwRecLen -= c;
153 while(c--)
154 {
155 circbuf[cbptr = (cbptr+1)%2048] = getc(fin);
156 }
157 return circbuf[outptr = (outptr+1)%2048];
158 }
159 else if (c >= 0x80 && c <= 0xBF)
160 {
161 int m,n;
162 c <<= 8;
163 c += getc(fin);
164 dwRecLen--;
165 m = (c & 0x3FFF) >> COUNT_BITS;
166 n = c & ((1<<COUNT_BITS) - 1);
167 n += 3;
168 while (n--)
169 {
170 cbptr = (cbptr+1)%2048;
171 circbuf[cbptr] = circbuf[(cbptr+2048-m)%2048];
172 }
173 return circbuf[outptr = (outptr+1)%2048];
174 }
175 else if (c >= 0xC0 && c <= 0xFF)
176 {
177 circbuf[cbptr = (cbptr+1)%2048] = ' ';
178 circbuf[cbptr = (cbptr+1)%2048] = c^0x80;
179 return circbuf[outptr = (outptr+1)%2048];
180 }
181}
182
183unsigned int Aportis::GetBS(unsigned int bn)
184{
185 DWORD dwPos;
186 WORD fs;
187
188 fseek(fin, 0x56 + 8*bn, SEEK_SET);
189 fread(&dwPos, 4, 1, fin);
190 dwPos = SwapLong(dwPos);
191 fseek(fin,dwPos,SEEK_SET);
192
193// gotorecordnumber(bn+1);
194 unsigned char ch;
195 fread(&ch,1,1,fin);
196 if (ch == 241)
197 {
198 fread(&fs,sizeof(fs),1,fin);
199 fs = SwapWord(fs);
200 }
201 else
202 fs = 0;
203 return fs;
204}
205
206unsigned int Aportis::locate()
207{
208 if (bCompressed == 4)
209 {
210 size_t cur = ftell(fin);
211 unsigned int clen = 0;
212 for (unsigned int i = 0; i < currentrec-1; i++)
213 {
214 unsigned int bs = GetBS(i);
215 if (bs == 0) break;
216 clen += bs;
217 }
218 fseek(fin,cur,SEEK_SET);
219 return clen+currentpos;
220 }
221 else
222 return (currentrec-1)*BlockSize+currentpos;
223}
224
225void Aportis::locate(unsigned int n)
226{
227 unsigned int offset;
228 // currentrec = (n >> OFFBITS);
229 switch (bCompressed)
230 {
231 case 4:
232 {
233 DWORD clen = 0;
234 offset = n;
235 unsigned int i;
236 for (i = 0; i < nRecs; i++)
237 {
238 unsigned int bs = GetBS(i);
239 if (bs == 0) break;
240 clen += bs;
241 if (clen > n) break;
242 offset = n - clen;
243 }
244 currentrec = i;
245 }
246 break;
247 case 1:
248 case 2:
249 default:
250 currentrec = n / BlockSize;
251 offset = n % BlockSize;
252 }
253
254 outptr = cbptr;
255 refreshbuffer();
256 while (currentpos < offset && getch() != EOF);
257}
258
259bool Aportis::refreshbuffer()
260{
261 if (currentrec < nRecs)
262 {
263 dwRecLen = recordlength(currentrec+1);
264 gotorecordnumber(currentrec+1);
265 if (bCompressed == 4)
266 {
267 unsigned char t[3];
268 fread(t,1,3,fin);
269 if (t[0] != 241)
270 {
271 printf("You shouldn't be here!\n");
272 return false;
273 }
274 dwRecLen -= 3;
275 }
276 /*
277 int n = fread(t.buf, 1, dwRecLen, fin);
278 t.len = n;
279 // if(bCompressed)
280 t.Decompress();
281
282 t.buf[t.Len()] = '\0';
283 */
284 currentpos = 0;
285 currentrec++;
286 return true;
287 }
288 else {
289 return false;
290 }
291}
diff --git a/noncore/apps/opie-reader/Aportis.h b/noncore/apps/opie-reader/Aportis.h
new file mode 100644
index 0000000..08016f4
--- a/dev/null
+++ b/noncore/apps/opie-reader/Aportis.h
@@ -0,0 +1,86 @@
1/*
2 Derived from makedoc9 by Pat Beirne
3*/
4
5#ifndef __Aportis_h
6#define __Aportis_h
7
8#include "CExpander.h"
9#include "pdb.h"
10
11typedef UInt32 DWORD;
12typedef UInt16 WORD;
13
14#define DISP_BITS 11
15#define COUNT_BITS 3
16/*
17// all numbers in these structs are big-endian, MAC format
18struct tDocHeader {
19 char sName[32];
20 DWORD dwUnknown1;
21 DWORD dwTime1;
22 DWORD dwTime2;
23 DWORD dwTime3;
24 DWORD dwLastSync;
25 DWORD ofsSort;
26 DWORD ofsCatagories;
27 DWORD dwCreator;
28 DWORD dwType;
29 DWORD dwUnknown2;
30 DWORD dwUnknown3;
31 WORD wNumRecs;
32};
33*/
34struct tDocRecord0 {
35 WORD wVersion;// 1=plain text, 2=compressed
36 WORD wSpare;
37 DWORD dwStoryLen; // in chars, when decompressed
38 WORD wNumRecs; // text records only; equals tDocHeader.wNumRecs-1
39 WORD wRecSize; // usually 0x1000
40 DWORD dwSpare2;
41};
42
43////////////// utilities //////////////////////////////////////
44
45inline WORD SwapWord(WORD r)
46{
47 return (r>>8) + (r<<8);
48}
49
50inline DWORD SwapLong(DWORD r)
51{
52 return ((r>>24) & 0xFF) + (r<<24) + ((r>>8) & 0xFF00) + ((r<<8) & 0xFF0000);
53}
54
55class Aportis : public CExpander, Cpdb {
56 DWORD dwLen;
57 WORD nRecs2;
58 DWORD dwTLen;
59 WORD nRecs;
60 WORD BlockSize;
61 DWORD dwRecLen;
62 int currentrec, currentpos;
63 unsigned int cbptr;
64 unsigned int outptr;
65 unsigned char circbuf[2048];
66 char bCompressed;
67public:
68 virtual void sizes(unsigned long& _file, unsigned long& _text)
69 {
70 _file = dwLen;
71 _text = dwTLen;
72 }
73 virtual bool hasrandomaccess() { return true; }
74 virtual ~Aportis() {}
75 Aportis();
76 virtual int openfile(const char *src);
77 virtual int getch();
78 virtual unsigned int locate();
79 virtual void locate(unsigned int n);
80 virtual CList<Bkmk>* getbkmklist();
81private:
82 bool refreshbuffer();
83 unsigned int GetBS(unsigned int bn);
84};
85
86#endif
diff --git a/noncore/apps/opie-reader/BuffDoc.cpp b/noncore/apps/opie-reader/BuffDoc.cpp
new file mode 100644
index 0000000..df2f4eb
--- a/dev/null
+++ b/noncore/apps/opie-reader/BuffDoc.cpp
@@ -0,0 +1,126 @@
1#include "BuffDoc.h"
2//#include <FL/fl_draw.h>
3#include "config.h"
4
5void BuffDoc::locate(unsigned int n)
6{
7 // qDebug("BuffDoc:locating:%u",n);
8
9 lastword[0] = '\0';
10 lastsizes[0] = laststartline = n;
11 lastispara = false;
12 // tchar linebuf[1024];
13 if (exp != NULL) exp->locate(n);
14 // qDebug("BuffDoc:Located");
15}
16
17bool BuffDoc::getline(CBuffer* buff, int w)
18{
19 if (exp == NULL)
20 {
21 (*buff)[0] = '\0';
22 return false;
23 }
24 int len = 0, ch, lastcheck = 0;
25 *buff = lastword.data();
26 lastcheck = len = buff->length();
27 // unsigned int slen = fl_widthi(buff->data(),len);
28#ifdef _UNICODE
29 unsigned int slen = m_fm->width(toQString(buff->data()),len);
30#else
31 unsigned int slen = m_fm->width(buff->data(),len);
32#endif
33 if (slen > w)
34 {
35 for ( ; len > 0; len--)
36 {
37 // if (fl_widthi(buff->data(),len) < w) break;
38#ifdef _UNICODE
39 if (m_fm->width(toQString(buff->data()),len) < w) break;
40#else
41 if (m_fm->width(buff->data(),len) < w) break;
42#endif
43 }
44 lastword = buff->data() + len - 1;
45 for (int i = 0; i < buff->length(); i++) lastsizes[i] = lastsizes[i+len-1];
46 (*buff)[len-1] = '-';
47 (*buff)[len] = '\0';
48 laststartline = lastsizes[len-1];
49 return true;
50 }
51 if (lastispara)
52 {
53 lastispara = false;
54 lastword[0] = '\0';
55 len = buff->length();
56 // while (fl_widthi(buff->data(),len) > w) len--;
57#ifdef _UNICODE
58 while (m_fm->width(toQString(buff->data()),len) > w) len--;
59#else
60 while (m_fm->width(buff->data(),len) > w) len--;
61#endif
62 (*buff)[len] = '\0';
63 laststartline = exp->locate();
64 return true;
65 }
66 lastispara = false;
67 for (int i = 0; i < len; i++) allsizes[i] = lastsizes[i];
68 while (slen < w)
69 {
70 lastcheck = len;
71 allsizes[len] = exp->locate();
72 while ((ch = getch()) != ' ' && ch != '\012' && ch != UEOF && len < 128)
73 {
74 (*buff)[len++] = ch;
75 allsizes[len] = exp->locate();
76 }
77 (*buff)[len] = 0;
78#ifdef _UNICODE
79 slen = m_fm->width(toQString(buff->data()),len);
80#else
81 slen = m_fm->width(buff->data(),len);
82#endif
83 (*buff)[len++] = ' ';
84 allsizes[len] = exp->locate();
85 if (slen < w && ch != ' ')
86 {
87 lastcheck = len;
88 break;
89 }
90 lastispara = (ch == '\012');
91 }
92 (*buff)[len] = '\0';
93 lastword = buff->data()+lastcheck;
94 for (int i = 0; i < lastword.length(); i++) lastsizes[i] = allsizes[i+lastcheck];
95 if (lastcheck > 0)
96 {
97 laststartline = allsizes[lastcheck];
98 (*buff)[lastcheck-1] = '\0';
99 }
100 else
101 {
102 laststartline = (lastcheck == len) ? exp->locate() : allsizes[lastcheck+1];
103 (*buff)[lastcheck] = '\0';
104 }
105// laststartline = sizes[lastcheck+1];
106// (*buff)[(lastcheck > 0) ? lastcheck-1:lastcheck] = '\0';
107 return (ch != UEOF);
108}
109
110bool BuffDoc::getline(CBuffer* buff, int w, int cw)
111{
112 if (exp == NULL)
113 {
114 (*buff)[0] = '\0';
115 return false;
116 }
117 tchar ch;
118 int i = 0;
119 while ((i < w/cw) && ((ch = getch()) != '\012') && (ch != UEOF))
120 {
121 (*buff)[i++] = ch;
122 }
123 (*buff)[i] = '\0';
124 laststartline = exp->locate();
125 return (ch != UEOF);
126}
diff --git a/noncore/apps/opie-reader/BuffDoc.h b/noncore/apps/opie-reader/BuffDoc.h
new file mode 100644
index 0000000..7c5ef9a
--- a/dev/null
+++ b/noncore/apps/opie-reader/BuffDoc.h
@@ -0,0 +1,138 @@
1#ifndef __BuffDoc_h
2#define __BuffDoc_h
3
4#include "CBuffer.h"
5#include "ZText.h"
6#include "Aportis.h"
7#include "ztxt.h"
8#include "ppm_expander.h"
9#include "CFilter.h"
10#include <qfontmetrics.h>
11#include <qmessagebox.h>
12
13class BuffDoc
14{
15 CBuffer lastword;
16 CSizeBuffer lastsizes, allsizes;
17 size_t laststartline;
18 bool lastispara;
19 CExpander* exp;
20 CFilterChain* filt;
21 QFontMetrics* m_fm;
22 public:
23 ~BuffDoc()
24 {
25 delete filt;
26 delete exp;
27 }
28 BuffDoc() : m_fm(NULL)
29 {
30 exp = NULL;
31 filt = NULL;
32 // qDebug("Buffdoc created");
33 }
34 bool empty() { return (exp == NULL); }
35 void setfm(QFontMetrics* fm)
36 {
37 m_fm = fm;
38 // qDebug("Buffdoc:setfm");
39 }
40 void setfilter(CFilterChain* _f)
41 {
42 if (filt != NULL) delete filt;
43 filt = _f;
44 filt->setsource(exp);
45 }
46 CList<Bkmk>* getbkmklist() { return exp->getbkmklist(); }
47 bool hasrandomaccess() { return (exp == NULL) ? false : exp->hasrandomaccess(); }
48 bool iseol() { return (lastword[0] == '\0'); }
49 int openfile(QWidget* _parent, const char *src)
50 {
51 // qDebug("BuffDoc:Openfile:%s", src);
52 // qDebug("Trying aportis %x",exp);
53 if (exp != NULL) delete exp;
54 lastword[0] = '\0';
55 lastsizes[0] = laststartline = 0;
56 lastispara = false;
57 /*
58 exp = new Text;
59 int ret = exp->openfile(src);
60 */
61
62 exp = new Aportis;
63 // qDebug("Calling openfile");
64 int ret = exp->openfile(src);
65 // qDebug("Called openfile");
66 if (ret == -1)
67 {
68 // qDebug("problem opening source file:%s",src);
69 delete exp;
70 exp = NULL;
71 return ret;
72 }
73 if (ret == -2)
74 {
75
76 delete exp;
77 // qDebug("Trying ztxt");
78 exp = new ztxt;
79 ret = exp->openfile(src);
80 }
81#ifndef SMALL
82 if (ret != 0)
83 {
84 delete exp;
85 // qDebug("Trying ppms");
86 exp = new ppm_expander;
87 ret = exp->openfile(src);
88 }
89
90 if (ret != 0)
91 {
92 delete exp;
93 exp = new Text;
94 // qDebug("Trying text");
95 ret = exp->openfile(src);
96 }
97#else
98 if (ret != 0)
99 {
100 delete exp;
101 exp = new Text;
102 ret = exp->openfile(src);
103 }
104#endif
105 if (ret != 0)
106 {
107 delete exp;
108 QMessageBox::information(_parent, "QTReader", "Unknown file compression type","Try another file");
109 return ret;
110 }
111 // qDebug("Doing final open:%x:%x",exp,filt);
112
113 lastword[0] = '\0';
114 lastsizes[0] = laststartline = 0;
115 lastispara = false;
116 exp->locate(0);
117 filt->setsource(exp);
118 // qDebug("BuffDoc:file opened");
119 return 0;
120 }
121 int getch() { return (exp == NULL) ? UEOF : filt->getch(); }
122 unsigned int locate() { return (exp == NULL) ? 0 : laststartline; }
123 void locate(unsigned int n);
124 bool getline(CBuffer* buff, int w);
125 bool getline(CBuffer* buff, int w, int cw);
126 void sizes(unsigned long& fs, unsigned long& ts) { exp->sizes(fs,ts); }
127 int getpara(CBuffer& buff)
128 {
129 int ch, i = 0;
130 while ((ch = getch()) != 10 && ch != UEOF) buff[i++] = ch;
131 buff[i] = '\0';
132 if (i == 0 && ch == UEOF) i = -1;
133 laststartline = exp->locate();
134 return i;
135 }
136};
137
138#endif
diff --git a/noncore/apps/opie-reader/CBuffer.cpp b/noncore/apps/opie-reader/CBuffer.cpp
new file mode 100644
index 0000000..db52476
--- a/dev/null
+++ b/noncore/apps/opie-reader/CBuffer.cpp
@@ -0,0 +1,35 @@
1#include "CBuffer.h"
2
3CBuffer& CBuffer::operator=(const tchar*sztmp)
4{
5 int i;
6 for (i = 0; sztmp[i] != '\0'; i++) (*this)[i] = sztmp[i];
7 (*this)[i] = '\0';
8 return *this;
9}
10
11tchar& CBuffer::operator[](int i)
12{
13 if (i >= len)
14 {
15 tchar *newbuff = new tchar[i+1];
16 memcpy(newbuff,buffer,sizeof(tchar)*len);
17 delete [] buffer;
18 buffer = newbuff;
19 len = i+1;
20 }
21 return buffer[i];
22}
23
24size_t& CSizeBuffer::operator[](int i)
25{
26 if (i >= len)
27 {
28 size_t *newbuff = new size_t[i+1];
29 memcpy(newbuff,buffer,sizeof(size_t)*len);
30 delete [] buffer;
31 buffer = newbuff;
32 len = i+1;
33 }
34 return buffer[i];
35}
diff --git a/noncore/apps/opie-reader/CBuffer.h b/noncore/apps/opie-reader/CBuffer.h
new file mode 100644
index 0000000..9807d27
--- a/dev/null
+++ b/noncore/apps/opie-reader/CBuffer.h
@@ -0,0 +1,45 @@
1#ifndef __CBUFFER_H
2#define __CBUFFER_H
3
4#include <stdlib.h>
5#include <string.h>
6#include "config.h"
7
8class CBuffer
9{
10 size_t len;
11 tchar *buffer;
12 CBuffer(const CBuffer&);
13 public:
14 CBuffer& operator=(const tchar*sztmp);
15#ifdef _UNICODE
16 size_t length() { return ustrlen(buffer); }
17#else
18 size_t length() { return strlen(buffer); }
19#endif
20 tchar* data() { return buffer; }
21 CBuffer(size_t n = 16) : len(n)
22 {
23 buffer = new tchar[len];
24 buffer[0] = '\0';
25 }
26 ~CBuffer() { delete [] buffer; }
27 tchar& operator[](int i);
28};
29
30class CSizeBuffer
31{
32 size_t len;
33 size_t *buffer;
34 CSizeBuffer(const CSizeBuffer&);
35 public:
36 size_t* data() { return buffer; }
37 CSizeBuffer(size_t n = 16) : len(n)
38 {
39 buffer = new size_t[len];
40 }
41 ~CSizeBuffer() { delete [] buffer; }
42 size_t& operator[](int i);
43};
44
45#endif
diff --git a/noncore/apps/opie-reader/CEncoding.cpp b/noncore/apps/opie-reader/CEncoding.cpp
new file mode 100644
index 0000000..18d18d3
--- a/dev/null
+++ b/noncore/apps/opie-reader/CEncoding.cpp
@@ -0,0 +1,150 @@
1#include <stdio.h>
2#include "CEncoding.h"
3
4tchar CUtf8::getch()
5{
6 int iret = parent->getch();
7 if (iret == EOF) return UEOF;
8 tchar ret = iret;
9 int count = 0;
10 if (ret & (1 << 7))
11 {
12 unsigned char flags = ret << 1;
13 while ((flags & (1 << 7)) != 0)
14 {
15 ret <<= 6;
16 ret += parent->getch() & 0x3f;
17 flags <<= 1;
18 count++;
19 }
20 switch (count)
21 {
22 case 0:
23 break;
24 case 1:
25 ret &= 0x07ff;
26 break;
27 case 2:
28 break;
29 case 3:
30 case 4:
31 case 5:
32 default:
33 printf("Only 16bit unicode supported...");
34 }
35 }
36 return ret;
37}
38
39
40tchar CUcs16be::getch()
41{
42 int iret = parent->getch();
43 if (iret == EOF) return UEOF;
44 tchar ret = iret;
45 return (ret << 8) + parent->getch();
46}
47
48tchar CUcs16le::getch()
49{
50 int iret = parent->getch();
51 if (iret == EOF) return UEOF;
52 tchar ret = iret;
53 return ret + (parent->getch() << 8);
54}
55
56tchar Ccp1252::getch()
57{
58 int iret = parent->getch();
59 switch (iret)
60 {
61 case EOF:
62 return UEOF;
63 case 0x80:
64 return 0x20ac;
65 case 0x82:
66 return 0x201a;
67 case 0x83:
68 return 0x0192;
69 case 0x84:
70 return 0x201e;
71 case 0x85:
72 return 0x2026;
73 case 0x86:
74 return 0x2020;
75 case 0x87:
76 return 0x2021;
77 case 0x88:
78 return 0x02c6;
79 case 0x89:
80 return 0x2030;
81 case 0x8a:
82 return 0x0160;
83 case 0x8b:
84 return 0x2039;
85 case 0x8c:
86 return 0x0152;
87 case 0x8e:
88 return 0x017d;
89 case 0x91:
90 return 0x2018;
91 case 0x92:
92 return 0x2019;
93 case 0x93:
94 return 0x201c;
95 case 0x94:
96 return 0x201d;
97 case 0x95:
98 return 0x2022;
99 case 0x96:
100 return 0x2013;
101 case 0x97:
102 return 0x2014;
103 case 0x98:
104 return 0x02dc;
105 case 0x99:
106 return 0x2122;
107 case 0x9a:
108 return 0x0161;
109 case 0x9b:
110 return 0x203a;
111 case 0x9c:
112 return 0x0153;
113 case 0x9e:
114 return 0x017e;
115 case 0x9f:
116 return 0x0178;
117 default:
118 return iret;
119 }
120}
121
122tchar CPalm::getch()
123{
124 tchar iret = Ccp1252::getch();
125 switch (iret)
126 {
127 case 0x18:
128 return 0x2026;
129 case 0x19:
130 return 0x2007;
131 case 0x8d:
132 return 0x2662;
133 case 0x8e:
134 return 0x2663;
135 case 0x8f:
136 return 0x2661;
137 case 0x90:
138 return 0x2660;
139 default:
140 return iret;
141 }
142}
143
144tchar CAscii::getch()
145{
146 int iret = parent->getch();
147 if (iret == EOF) return UEOF;
148 return iret;
149}
150
diff --git a/noncore/apps/opie-reader/CEncoding.h b/noncore/apps/opie-reader/CEncoding.h
new file mode 100644
index 0000000..1eee29e
--- a/dev/null
+++ b/noncore/apps/opie-reader/CEncoding.h
@@ -0,0 +1,53 @@
1#ifndef __CENCODING_H
2#define __CENCODING_H
3
4#include "CExpander.h"
5
6class CEncoding : public CCharacterSource
7{
8 friend class CFilterChain;
9 protected:
10 CExpander* parent;
11public:
12 CEncoding() : parent(NULL) {}
13 void setparent(CExpander* p) { parent = p; }
14 virtual ~CEncoding() {};
15};
16
17class CUtf8 : public CEncoding
18{
19public:
20 tchar getch();
21};
22
23class CUcs16be : public CEncoding
24{
25public:
26 tchar getch();
27};
28
29class CUcs16le : public CEncoding
30{
31public:
32 tchar getch();
33};
34
35class Ccp1252 : public CEncoding
36{
37public:
38 virtual tchar getch();
39};
40
41class CPalm : public Ccp1252
42{
43public:
44 tchar getch();
45};
46
47class CAscii : public CEncoding
48{
49public:
50 tchar getch();
51};
52
53#endif
diff --git a/noncore/apps/opie-reader/CExpander.h b/noncore/apps/opie-reader/CExpander.h
new file mode 100644
index 0000000..07c14fa
--- a/dev/null
+++ b/noncore/apps/opie-reader/CExpander.h
@@ -0,0 +1,145 @@
1#ifndef __CExpander_h
2#define __CExpander_h
3
4#include "my_list.h"
5#include "config.h"
6
7class Bkmk
8{
9 friend class BkmkFile;
10 tchar* m_name;
11 unsigned int m_position;
12 public:
13 Bkmk() : m_name(NULL), m_position(0) {};
14 Bkmk(const tchar* _nm, unsigned int _p) : m_position(_p)
15 {
16 int len = ustrlen(_nm)+1;
17 m_name = new tchar[len];
18 for (int i = 0; i < len; i++) m_name[i] = _nm[i];
19 }
20 Bkmk(const Bkmk& rhs) : m_name(NULL)
21 {
22 *this = rhs;
23 }
24 ~Bkmk() { if (m_name != NULL) delete [] m_name; }
25 unsigned int value() const { return m_position; }
26 tchar *name() const { return m_name; }
27 bool operator<(const Bkmk& rhs) { return (m_position < rhs.m_position); }
28 Bkmk& operator=(const Bkmk& rhs)
29 {
30 if (m_name != NULL) delete [] m_name;
31 if (rhs.m_name != NULL)
32 {
33 int len = ustrlen(rhs.m_name)+1;
34 m_name = new tchar[len];
35 for (int i = 0; i < len; i++) m_name[i] = rhs.m_name[i];
36 }
37 else
38 m_name = NULL;
39 m_position = rhs.m_position;
40 return *this;
41 }
42 bool operator==(const Bkmk& rhs)
43 {
44 return (m_position == rhs.m_position && ustrcmp(m_name,rhs.m_name) == 0);
45 }
46};
47
48class BkmkFile
49{
50 FILE* f;
51 bool wt;
52public:
53 BkmkFile(const char *fnm, bool w = false)
54 :
55 wt(w)
56 {
57 if (w)
58 f = fopen(fnm, "wb");
59 else
60 f = fopen(fnm, "rb");
61 }
62 ~BkmkFile()
63 {
64 if (f != NULL) fclose(f);
65 }
66 void write(tchar* nm, const unsigned int& pos)
67 {
68 if (f != NULL)
69 {
70 unsigned short ln = ustrlen(nm);
71 fwrite(&ln,sizeof(ln),1,f);
72 fwrite(nm,sizeof(tchar),ln,f);
73 fwrite(&pos,sizeof(pos),1,f);
74 }
75 }
76 void write(const Bkmk& b) { write(b.name(), b.value()); }
77 void write(CList<Bkmk>& bl)
78 {
79 if (f != NULL)
80 {
81 for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++)
82 {
83 write(*i);
84 }
85 }
86 }
87 Bkmk* read()
88 {
89 Bkmk* b = NULL;
90 if (f != NULL)
91 {
92 unsigned short ln;
93 if (fread(&ln,sizeof(ln),1,f) == 1)
94 {
95 b = new Bkmk;
96 b->m_name = new tchar[ln+1];
97 fread(b->m_name,sizeof(tchar),ln,f);
98 b->m_name[ln] = 0;
99 fread(&b->m_position,sizeof(b->m_position),1,f);
100 }
101 }
102 return b;
103 }
104 CList<Bkmk>* readall()
105 {
106 CList<Bkmk>* bl = NULL;
107 if (f != NULL)
108 {
109 bl = new CList<Bkmk>;
110 while (1)
111 {
112 Bkmk* b = read();
113 if (b == NULL) break;
114 bl->push_back(*b);
115 delete b;
116 }
117 }
118 return bl;
119 }
120};
121
122class CCharacterSource
123{
124 public:
125#ifdef _UNICODE
126 virtual tchar getch() = 0;
127#else
128 virtual int getch() = 0;
129#endif
130};
131
132class CExpander
133{
134 public:
135 CExpander() {};
136 virtual ~CExpander() {};
137 virtual int openfile(const char *src) = 0;
138 virtual unsigned int locate() = 0;
139 virtual void locate(unsigned int n) = 0;
140 virtual bool hasrandomaccess() = 0;
141 virtual void sizes(unsigned long& file, unsigned long& text) = 0;
142 virtual CList<Bkmk>* getbkmklist() { return NULL; }
143 virtual int getch() = 0;
144};
145#endif
diff --git a/noncore/apps/opie-reader/CFilter.h b/noncore/apps/opie-reader/CFilter.h
new file mode 100644
index 0000000..4f609dc
--- a/dev/null
+++ b/noncore/apps/opie-reader/CFilter.h
@@ -0,0 +1,354 @@
1#ifndef __CFILTER_H
2#define __CFILTER_H
3
4#include "CExpander.h"
5#include "CEncoding.h"
6
7class CFilter : public CCharacterSource
8{
9 friend class CFilterChain;
10 protected:
11 CCharacterSource* parent;
12public:
13 CFilter() : parent(NULL) {}
14 void setparent(CCharacterSource* p) { parent = p; }
15 virtual ~CFilter() {};
16};
17
18class vanilla : public CFilter
19{
20public:
21 vanilla() {}
22 virtual ~vanilla() {}
23#ifdef _UNICODE
24 virtual tchar getch()
25#else
26 virtual int getch()
27#endif
28 {
29 return parent->getch();
30 }
31};
32
33class CFilterChain
34{
35 CExpander* expander;
36 CEncoding* encoder;
37 CFilter* first;
38 CCharacterSource* front;
39 public:
40 CFilterChain(CEncoding* _e) : encoder(_e), first(NULL), front(_e) {};
41 ~CFilterChain()
42 {
43 CCharacterSource* p = front;
44 while (p != encoder)
45 {
46 CFilter* pnext = (CFilter*)p;
47 p = ((CFilter*)p)->parent;
48 delete pnext;
49 }
50 delete encoder;
51 }
52 int getch() { return front->getch(); }
53 void addfilter(CFilter* p)
54 {
55 if (first == NULL)
56 {
57 front = first = p;
58 p->setparent(encoder);
59 }
60 else
61 {
62 p->setparent(front);
63 front = p;
64 }
65 }
66 void setsource(CExpander* p)
67 {
68 expander = p;
69 encoder->setparent(p);
70 }
71 void setencoder(CEncoding* p)
72 {
73 delete encoder;
74 encoder = p;
75 first->setparent(p);
76 encoder->setparent(expander);
77 }
78};
79
80class stripcr : public CFilter
81{
82public:
83 stripcr() {}
84 virtual ~stripcr() {}
85#ifdef _UNICODE
86 virtual tchar getch()
87 {
88 tchar ch;
89 do
90 {
91 ch = parent->getch();
92 }
93 while (ch == 13);
94 return ch;
95 }
96#else
97 virtual int getch()
98 {
99 int ch;
100 do
101 {
102 ch = parent->getch();
103 }
104 while (ch == 13);
105 return ch;
106 }
107#endif
108};
109
110class dehyphen : public CFilter
111{
112 bool m_bCharWaiting;
113 tchar m_nextChar;
114 public:
115 dehyphen() : m_bCharWaiting(false) {}
116 virtual ~dehyphen() {}
117 virtual tchar getch()
118 {
119 if (m_bCharWaiting)
120 {
121 m_bCharWaiting = false;
122 return m_nextChar;
123 }
124 tchar ch = parent->getch();
125 if (ch != '-') return ch;
126 m_nextChar = parent->getch();
127 if (m_nextChar != 10)
128 {
129 m_bCharWaiting = true;
130 return '-';
131 }
132 return parent->getch();
133 }
134};
135
136class striphtml : public CFilter
137{
138public:
139 striphtml() {}
140 virtual ~striphtml() {}
141#ifdef _UNICODE
142 virtual tchar getch()
143 {
144 tchar ch;
145 ch = parent->getch();
146 while (ch == '<')
147 {
148 while (ch != '>')
149 {
150 ch = parent->getch();
151 }
152 ch = parent->getch();
153 }
154 if (ch == '&')
155 {
156 ch = parent->getch();
157 if (ch == '#')
158 {
159 int id = 0;
160 while ((ch = parent->getch()) != ';') id = 10*id+ch-'0';
161 ch = id;
162 }
163 }
164 return ch;
165 }
166#else
167 virtual int getch()
168 {
169 int ch;
170 ch = parent->getch();
171 while (ch == '<')
172 {
173 while (ch != '>')
174 {
175 ch = parent->getch();
176 }
177 ch = parent->getch();
178 }
179 if (ch == '&')
180 {
181 ch = parent->getch();
182 if (ch == '#')
183 {
184 int id = 0;
185 while ((ch = parent->getch()) != ';') id = 10*id+ch-'0';
186 ch = id;
187 }
188 }
189 return ch;
190 }
191#endif
192};
193
194class unindent : public CFilter
195{
196 tchar lc;
197public:
198 unindent() : lc(0) {}
199 virtual ~unindent() {}
200#ifdef _UNICODE
201 virtual tchar getch()
202 {
203 tchar ch;
204 if (lc == 10)
205 {
206 while ((ch = parent->getch()) == ' ');
207 }
208 else ch = parent->getch();
209 lc = ch;
210 return ch;
211 }
212#else
213 virtual int getch()
214 {
215 int ch;
216 if (lc == 10)
217 {
218 while ((ch = parent->getch()) == ' ');
219 }
220 else ch = parent->getch();
221 lc = ch;
222 return ch;
223 }
224#endif
225};
226
227#ifdef _UNICODE
228class repara : public CFilter
229{
230 tchar tch;
231public:
232 repara() : tch(0) {}
233 virtual ~repara() {}
234 virtual tchar getch()
235 {
236 tchar ch = parent->getch();
237 if (ch == 10)
238 {
239 if (tch == 10)
240 {
241 return ch;
242 }
243 else
244 {
245 tch = ch;
246 return ' ';
247 }
248 }
249 tch = ch;
250 return ch;
251 }
252};
253#else
254class repara : public CFilter
255{
256 int tch;
257public:
258 repara() : tch(0) {}
259 virtual ~repara() {}
260 virtual int getch()
261 {
262 int ch = parent->getch();
263 if (ch == 10)
264 {
265 if (tch == 10)
266 {
267 return ch;
268 }
269 else
270 {
271 tch = ch;
272 return ' ';
273 }
274 }
275 tch = ch;
276 return ch;
277 }
278};
279#endif
280
281class indenter : public CFilter
282{
283 int amnt;
284 int indent;
285public:
286 indenter(int _a=5) : amnt(_a), indent(0) {}
287 virtual ~indenter() {}
288#ifdef _UNICODE
289 virtual tchar getch()
290 {
291 if (indent > 0)
292 {
293 indent--;
294 return ' ';
295 }
296 tchar ch = parent->getch();
297 if (ch == 10)
298 {
299 indent = amnt;
300 }
301 return ch;
302 }
303#else
304 virtual int getch()
305 {
306 if (indent > 0)
307 {
308 indent--;
309 return ' ';
310 }
311 int ch = parent->getch();
312 if (ch == 10)
313 {
314 indent = amnt;
315 }
316 return ch;
317 }
318#endif
319};
320
321class dblspce : public CFilter
322{
323 bool lastlf;
324public:
325 dblspce() : lastlf(false) {}
326 virtual ~dblspce() {}
327#ifdef _UNICODE
328 virtual tchar getch()
329 {
330 if (lastlf)
331 {
332 lastlf = false;
333 return 10;
334 }
335 tchar ch = parent->getch();
336 lastlf = (ch == 10);
337 return ch;
338 }
339#else
340 virtual int getch()
341 {
342 if (lastlf)
343 {
344 lastlf = false;
345 return 10;
346 }
347 int ch = parent->getch();
348 lastlf = (ch == 10);
349 return ch;
350 }
351#endif
352};
353
354#endif
diff --git a/noncore/apps/opie-reader/QTReader.cpp b/noncore/apps/opie-reader/QTReader.cpp
new file mode 100644
index 0000000..6251812
--- a/dev/null
+++ b/noncore/apps/opie-reader/QTReader.cpp
@@ -0,0 +1,1034 @@
1/****************************************************************************
2** $Id$
3**
4** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
5**
6** This file is part of an example program for Qt. This example
7** program may be used, distributed and modified without limitation.
8**
9*****************************************************************************/
10
11#include "config.h"
12#include "QTReader.h"
13#include "QTReaderApp.h"
14#include <qpe/qpeapplication.h>
15#include <math.h>
16#include <ctype.h>
17#include <stdio.h> //for sprintf
18#include <qpe/config.h>
19#include <qpe/applnk.h>
20#include <qfontdatabase.h>
21#include <qpe/global.h>
22#include <qpe/qcopenvelope_qws.h>
23
24#ifdef _UNICODE
25const char *QTReader::fonts[] = { "unifont", "Courier", "Times", 0 };
26#else
27const char *QTReader::fonts[] = { "Helvetica", "Courier", "Times", 0 };
28#endif
29//const int QTReader::fontsizes[] = { 8, 10, 12, 14, 18, 24, 30, 40, 50, 60, 70, 80, 90, 100, 0 };
30
31//const tchar *QTReader::fonts[] = { "unifont", "fixed", "micro", "smoothtimes", "Courier", "Times", 0 };
32//const int QTReader::fontsizes[] = {10,16,17,22,0};
33//const tchar *QTReader::fonts[] = { "verdana", "Courier", "Times", 0 };
34//const int QTReader::fontsizes[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,0};
35
36QTReader::QTReader( QWidget *parent=0, const char *name=0, WFlags f = 0) :
37 QWidget(parent, name, f),
38 m_delay(100),
39 m_scrolldy(0),
40 m_autoScroll(false),
41 textarray(NULL),
42 locnarray(NULL),
43 numlines(0),
44 m_fontname("unifont"),
45 m_fm(NULL)
46{
47 m_overlap = 1;
48 fontsizes = NULL;
49// init();
50}
51/*
52QTReader::QTReader( const QString& filename, QWidget *parent=0, const tchar *name=0, WFlags f = 0) :
53 QWidget(parent, name, f),
54 m_textfont(0),
55 m_textsize(1),
56 textarray(NULL),
57 numlines(0),
58 bstripcr(true),
59 bunindent(false),
60 brepara(false),
61 bdblspce(false),
62 btight(false),
63 bindenter(0),
64 m_fm(NULL)
65{
66 init();
67 // qDebug("Load_file(1)");
68 load_file((const tchar*)filename);
69}
70*/
71
72long QTReader::real_delay()
73{
74 return ( 8976 + m_delay ) / ( m_linespacing * m_linespacing );
75}
76
77void QTReader::mouseReleaseEvent( QMouseEvent* _e )
78//void QTReader::mouseDoubleClickEvent( QMouseEvent* _e )
79{
80 if (textarray != NULL)
81 {
82 //printf("(%u, %u)\n", _e->x(), _e->y());
83 QString wrd = QString::null;
84 int lineno = _e->y()/m_linespacing;
85 if (m_bMonoSpaced)
86 {
87 int chno = _e->x()/m_charWidth;
88 if (chno < ustrlen(textarray[lineno]->data()))
89 {
90 wrd[0] = textarray[lineno]->data()[chno];
91 }
92 }
93 else
94 {
95 CBuffer* t = textarray[lineno];
96 int first = 0;
97 while (1)
98 {
99 int i = first+1;
100 // while ((*t)[i] != ' ' && (*t)[i] != 0) i++;
101 while (QChar((*t)[i]).isLetter() && (*t)[i] != 0) i++;
102 if (m_fm->width(toQString(t->data()), i) > _e->x())
103 {
104 wrd = toQString(t->data()+first, i - first);
105 break;
106 }
107 // while ((*t)[i] == ' ' && (*t)[i] != 0) i++;
108 while (!QChar((*t)[i]).isLetter() && (*t)[i] != 0) i++;
109 if ((*t)[i] == 0) break;
110 first = i;
111 }
112 }
113 if (!wrd.isEmpty())
114 {
115 QClipboard* cb = QApplication::clipboard();
116 cb->setText(wrd);
117 Global::statusMessage(wrd);
118 if (!m_targetapp.isEmpty() && !m_targetmsg.isEmpty())
119 {
120 QCopEnvelope e(("QPE/Application/"+m_targetapp).utf8(), (m_targetmsg+"(QString)").utf8());
121 e << wrd;
122 }
123 }
124 }
125}
126
127void QTReader::focusInEvent(QFocusEvent* e)
128{
129 if (m_autoScroll) timer->start(real_delay(), false);
130 update();
131}
132
133void QTReader::focusOutEvent(QFocusEvent* e)
134{
135 if (m_autoScroll)
136 {
137 timer->stop();
138 m_scrolldy = 0;
139 }
140}
141
142#include <qapplication.h>
143#include <qdrawutil.h>
144#include <unistd.h>
145
146void QTReader::goDown()
147{
148 if (m_bpagemode)
149 {
150 dopagedn();
151 }
152 else
153 {
154 lineDown();
155 }
156}
157
158void QTReader::goUp()
159{
160 if (m_bpagemode)
161 {
162 dopageup();
163 }
164 else
165 {
166 lineUp();
167 }
168}
169
170void QTReader::keyPressEvent(QKeyEvent* e)
171{
172 switch (e->key())
173 {
174 case Key_Down:
175 {
176 e->accept();
177 if (m_autoScroll)
178 {
179 if (m_delay < 59049)
180 {
181 m_delay = (3*m_delay)/2;
182 timer->changeInterval(real_delay());
183 }
184 else
185 {
186 m_delay = 59049;
187 }
188 }
189 else
190 {
191 goDown();
192 }
193 }
194 break;
195 case Key_Up:
196 {
197 e->accept();
198 if (m_autoScroll)
199 {
200 if (m_delay > 1024)
201 {
202 m_delay = (2*m_delay)/3;
203 timer->changeInterval(real_delay());
204 }
205 else
206 {
207 m_delay = 1024;
208 }
209 }
210 else
211 {
212 goUp();
213 }
214 }
215 break;
216 /*
217 case Key_Left:
218 {
219 e->accept();
220 if (m_textfont > 0)
221 {
222 m_textfont--;
223 setfont(NULL);
224 locate(pagelocate());
225 update();
226 }
227 }
228 break;
229 case Key_Right:
230 {
231 e->accept();
232 if (fonts[++m_textfont] == 0)
233 {
234 m_textfont--;
235 }
236 else
237 {
238 setfont(NULL);
239 locate(pagelocate());
240 update();
241 }
242 }
243 break;
244 */
245 case Key_Right:
246 {
247 e->accept();
248 if (fontsizes[++m_textsize] == 0)
249 {
250 m_textsize--;
251 }
252 else
253 {
254 bool sc = m_autoScroll;
255 m_autoScroll = false;
256 setfont(NULL);
257 locate(pagelocate());
258 update();
259 m_autoScroll = sc;
260 if (m_autoScroll) autoscroll();
261 }
262 }
263 break;
264 case Key_Left:
265 {
266 e->accept();
267 if (m_textsize > 0)
268 {
269 bool sc = m_autoScroll;
270 m_autoScroll = false;
271 m_textsize--;
272 setfont(NULL);
273 locate(pagelocate());
274 update();
275 m_autoScroll = sc;
276 if (m_autoScroll) autoscroll();
277 }
278 }
279 break;
280 case Key_Space:
281 //case Key_Enter:
282 case Key_Return:
283 {
284 e->accept();
285 setautoscroll(!m_autoScroll);
286 ((QTReaderApp*)parent()->parent())->setScrollState(m_autoScroll);
287 }
288 break;
289 default:
290 e->ignore();
291 }
292}
293
294void QTReader::setautoscroll(bool _sc)
295{
296 if (_sc == m_autoScroll) return;
297 if (m_autoScroll)
298 {
299 m_autoScroll = false;
300 }
301 else
302 {
303 m_autoScroll = true;
304 autoscroll();
305 }
306}
307
308bool QTReader::getline(CBuffer *buff)
309{
310 if (m_bMonoSpaced)
311 {
312 return buffdoc.getline(buff ,width(), m_charWidth);
313 }
314 else
315 {
316 return buffdoc.getline(buff, width());
317 }
318}
319
320void QTReader::doscroll()
321{
322 if (!m_autoScroll)
323 {
324 timer->stop();
325 return;
326 }
327// timer->changeInterval(real_delay());
328 QPainter p( this );
329 QBrush b( white);
330 bitBlt(this,0,0,this,0,1,width(),-1);
331 qDrawPlainRect(&p,0,height() - 2,width(),2,white,1,&b);
332
333 if (++m_scrolldy == m_linespacing)
334 {
335 setfont(&p);
336 m_scrolldy = 0;
337 // qDrawPlainRect(&p,0,height() - m_linespacing,width(),m_linespacing,white,1,&b);
338 pagepos = locnarray[1];
339 CBuffer* buff = textarray[0];
340 for (int i = 1; i < numlines; i++)
341 {
342 textarray[i-1] = textarray[i];
343 locnarray[i-1] = locnarray[i];
344 }
345 locnarray[numlines-1] = locate();
346 if (getline(buff))
347 {
348 textarray[numlines-1] = buff;
349 drawText( p, 0, height() - m_descent - 2, buff->data());
350 mylastpos = locate();
351 }
352 else
353 {
354 // (*buff)[0] = '\0';
355 textarray[numlines-1] = buff;
356 m_autoScroll = false;
357 ((QTReaderApp*)parent()->parent())->setScrollState(m_autoScroll);
358 }
359 }
360}
361
362void QTReader::drawText(QPainter& p, int x, int y, tchar* _text)
363{
364 QString text = toQString(_text);
365 if (m_bMonoSpaced)
366 {
367 for (int i = 0; i < text.length(); i++)
368 {
369 p.drawText( x+i*m_charWidth, y, QString(text[i]) );
370 }
371 }
372 else
373 {
374 p.drawText( x, y, text );
375 }
376}
377
378void QTReader::autoscroll()
379{
380 timer->start(real_delay(), false);
381}
382
383void QTReader::setfont(QPainter* p)
384{
385 // qDebug("Fontsize = %u",fontsizes[m_textsize]);
386 // qDebug("SetFont %x",p);
387 QFont font(m_fontname, fontsizes[m_textsize], (m_bBold) ? QFont::Bold : QFont::Normal );
388 m_charWidth = (m_charpc*fontsizes[m_textsize])/100;
389 if (m_charWidth <= 0) m_charWidth = 1;
390// font.setFixedPitch(m_bMonoSpaced);
391// qDebug("Raw name = %s", (const char*)font.rawName());
392 if (p != NULL) p->setFont( font );
393 if (m_fm == NULL)
394 {
395 m_fm = new QFontMetrics(font);
396 buffdoc.setfm(m_fm);
397 }
398 else
399 {
400 *m_fm = QFontMetrics(font);
401 }
402 m_ascent = m_fm->ascent();
403 m_descent = m_fm->descent();
404 m_linespacing = m_fm->lineSpacing();
405}
406
407void QTReader::drawFonts( QPainter *p )
408{
409 setfont(p);
410 if (m_lastwidth != width())
411 {
412 m_lastwidth = width();
413 locate(pagepos);
414 }
415 else
416 {
417 int sl = screenlines();
418 if (sl < numlines)
419 {
420 //qDebug("df:<%u,%u>",sl,numlines);
421
422 size_t newpos = locnarray[sl];
423 CBuffer** nta = new CBuffer*[sl];
424 size_t* nla = new size_t[sl];
425 for (int i = 0; i < sl; i++)
426 {
427 nta[i] = textarray[i];
428 nla[i] = locnarray[i];
429 }
430 for (int i = sl; i < numlines; i++) delete textarray[i];
431 delete [] textarray;
432 delete [] locnarray;
433 textarray = nta;
434 locnarray = nla;
435 numlines = sl;
436 jumpto(mylastpos = newpos);
437 //locate(pagepos);
438 }
439 if (sl > numlines)
440 {
441 //qDebug("df:<%u,%u>",sl,numlines);
442 CBuffer** nta = new CBuffer*[sl];
443 size_t* nla = new size_t[sl];
444 for (int i = 0; i < numlines; i++)
445 {
446 nta[i] = textarray[i];
447 nla[i] = locnarray[i];
448 }
449 if (locate() != mylastpos) jumpto(mylastpos);
450 for (int i = numlines; i < sl; i++)
451 {
452 nta[i] = new CBuffer;
453 nla[i] = locate();
454 getline(nta[i]);
455 }
456 mylastpos = locate();
457 delete [] textarray;
458 delete [] locnarray;
459 textarray = nta;
460 locnarray = nla;
461 numlines = sl;
462 }
463 int ypos = (btight) ? 0 : m_ascent-m_linespacing;
464 // int linespacing = (tight) ? m_ascent : m_ascent+m_descent;
465 for (int i = 0; i < numlines; i++)
466 {
467 drawText( *p, 0, ypos += m_linespacing, textarray[i]->data());
468 }
469 /*
470
471
472
473 int nlines = height()/(fontmetric.ascent()+fontmetric.descent());
474 tchar buffer[1024];
475 for (int i = 0; i < nlines; i++)
476 {
477 y += fontmetric.ascent();
478 sprintf(buffer, "%d:%d:%s[%d]:Lines %d:%s", i+1, m_textfont, fonts[m_textfont], m_fs, nlines, (const tchar*)m_string);
479 drawText( *p, 0, y, buffer );
480 y += fontmetric.descent();
481 }
482 */
483 }
484 m_scrolldy = 0;
485}
486
487QString QTReader::firstword()
488{
489 if (m_bMonoSpaced)
490 {
491 return toQString(textarray[0]->data());
492 }
493 else
494 {
495 int start, end, len, j;
496 for (j = 0; j < numlines; j++)
497 {
498 len = textarray[j]->length();
499 for (start = 0; start < len && !isalpha((*textarray[j])[start]); start++);
500 if (start < len) break;
501 }
502 if (j < numlines)
503 {
504 QString ret = "";
505 for (end = start; end < len && isalpha((*textarray[j])[end]); end++)
506 ret += (*textarray[j])[end];
507 if (ret.isEmpty()) ret = "Current position";
508 return ret;
509 }
510 else
511 return "Current position";
512 }
513}
514
515//
516// Construct the QTReader with buttons.
517//
518
519void QTReader::ChangeFont(int tgt)
520{
521
522 QValueList<int>::Iterator it;
523
524// QValueList<int> sizes = QFontDatabase::pointSizes(m_fontname, (m_bBold) ? QFont::Bold : QFont::Normal);
525 QFontDatabase fdb;
526/*
527 QStringList styles = fdb.styles(m_fontname);
528 for ( QStringList::Iterator it = styles.begin(); it != styles.end(); ++it )
529 {
530 printf( "%s \n", (*it).latin1() );
531 }
532*/
533 QValueList<int> sizes = fdb.pointSizes(m_fontname, (m_bBold) ? QString("Bold") : QString::null);
534 uint n = sizes.count();
535 if (fontsizes != NULL) delete [] fontsizes;
536 fontsizes = new unsigned int[n+1];
537 uint i = 0;
538 uint best = 0;
539 for (it = sizes.begin(); it != sizes.end(); it++)
540 {
541 fontsizes[i] = (*it)/10;
542 if (abs(tgt-fontsizes[i]) < abs(tgt-fontsizes[best]))
543 {
544 best = i;
545 }
546 i++;
547 }
548 m_textsize = best;
549 fontsizes[i] = 0;
550 setfont(NULL);
551 QFont font(m_fontname, fontsizes[m_textsize], (m_bBold) ? QFont::Bold : QFont::Normal );
552 if (m_fm == NULL)
553 {
554 m_fm = new QFontMetrics(font);
555 buffdoc.setfm(m_fm);
556 }
557}
558
559void QTReader::init()
560{
561 // setCaption( "Qt Draw Demo Application" );
562
563 setBackgroundColor( white );
564// QPainter p(this);
565// p.setBackgroundMode( Qt::OpaqueMode );
566 buffdoc.setfilter(getfilter());
567 ChangeFont(m_textsize);
568 // setFocusPolicy(QWidget::StrongFocus);
569 // resize( 240, 320 );
570 //setFocus();
571 timer = new QTimer(this);
572 connect(timer, SIGNAL(timeout()), this, SLOT(doscroll()));
573// QMessageBox::information(this, "init", m_lastfile, 1);
574 m_lastwidth = width();
575 if (!m_lastfile.isEmpty())
576 {
577 m_string = DocLnk(m_lastfile).name();
578 load_file(m_lastfile);
579 }
580}
581
582//
583// Clean up
584//
585QTReader::~QTReader()
586{
587 if (fontsizes != NULL) delete [] fontsizes;
588#ifndef QT_NO_PRINTER
589 // delete printer;
590#endif
591}
592
593//
594// Calls the drawing function as specified by the radio buttons.
595//
596
597void QTReader::drawIt( QPainter *p )
598{
599 drawFonts(p);
600}
601
602//
603// Called when the print button is clicked.
604//
605/*
606void QTReader::printIt()
607{
608#ifndef QT_NO_PRINTER
609 if ( printer->setup( this ) ) {
610 QPainter paint;
611 if ( !paint.begin( printer ) )
612 return;
613 drawIt( &paint );
614 }
615#endif
616}
617*/
618//
619// Called when the widget needs to be updated.
620//
621
622void QTReader::paintEvent( QPaintEvent * )
623{
624 QPainter paint( this );
625 drawIt( &paint );
626}
627
628//
629// Called when the widget has been resized.
630// Moves the button group to the upper right corner
631// of the widget.
632
633/*
634void QTReader::resizeEvent( QResizeEvent * )
635{
636 // qDebug("resize:(%u,%u)", width(), height());
637 // bgroup->move( width()-bgroup->width(), 0 );
638}
639*/
640
641//
642// Create and display our widget.
643//
644/*
645int main( int argc, tchar **argv )
646{
647 QApplication app( argc, argv );
648 QTReader draw;
649 app.setMainWidget( &draw );
650 draw.setCaption("Qt Example - Drawdemo");
651 draw.show();
652 return app.exec();
653}
654*/
655
656
657bool QTReader::locate(unsigned long n) {
658 //printf("Locate\n");
659 buffdoc.locate(n);
660 // qDebug("&buffdoc.located");
661 fillbuffer();
662 // qDebug("&Buffer filled");
663 update();
664 // qDebug("&Located");
665 return true;
666}
667
668unsigned int QTReader::screenlines()
669{
670 // int linespacing = (tight) ? m_ascent : m_ascent+m_descent;
671 // return (height()-m_descent)/(m_linespacing);
672 return (height()-2)/(m_linespacing);
673};
674
675bool QTReader::fillbuffer() {
676 //printf("Fillbuffer\n");
677 m_scrolldy = 0;
678 int ch;
679 bool ret = false;
680 int delta = screenlines();
681 // qDebug("fillbuffer:%u-%u",delta,numlines);
682 if (delta != numlines)
683 {
684 if (textarray != NULL)
685 {
686 for (int i = 0; i < numlines; i++) delete textarray[i];
687 delete [] textarray;
688 delete [] locnarray;
689 }
690 numlines = delta;
691 textarray = new CBuffer*[numlines];
692 locnarray = new size_t[numlines];
693 for (int i = 0; i < numlines; i++) textarray[i] = new CBuffer;
694 }
695 // qDebug("fillbuffer:pagepos:%u",pagepos);
696 unsigned int oldpagepos = pagepos;
697// if (textarray != NULL)
698// pagepos = locnarray[0];
699// else
700 pagepos = locate();
701 for (int i = 0; i < delta; i++)
702 {
703 locnarray[i] = locate();
704 ch = getline(textarray[i]);
705 // if (ch == EOF) {
706 if (!ch)
707 {
708 if (i == 0)
709 {
710 pagepos = oldpagepos;
711 return false;
712 }
713 else
714 {
715 ret = true;
716 for (int j = i+1; j < delta; j++)
717 {
718 locnarray[j] = locnarray[j-1];
719 (*(textarray[j]))[0] = '\0';
720 }
721 break;
722 }
723 }
724 if (ch == '\012') ret = true;
725 }
726 mylastpos = locate();
727 // qDebug("fillbuffer:lastpos:%u",mylastpos);
728 return true;
729}
730
731
732void QTReader::dopagedn()
733{
734 if (m_overlap == 0)
735 {
736 if (locate() != mylastpos) jumpto(mylastpos);
737 }
738 else
739 {
740 if (m_overlap >= screenlines()) m_overlap = screenlines()/2;
741 jumpto(locnarray[screenlines()-m_overlap]);
742 }
743 if (fillbuffer())
744 {
745 update();
746 }
747}
748
749void QTReader::dopageup()
750{
751 CBuffer** buff = textarray;
752 unsigned int *loc = new unsigned int[numlines];
753 int cbptr = 0;
754 if (locate() != mylastpos) jumpto(mylastpos);
755 if (m_overlap >= screenlines()) m_overlap = screenlines()/2;
756 unsigned int target = locnarray[m_overlap];
757 if (buffdoc.hasrandomaccess())
758 {
759 unsigned int delta = locate()-pagelocate();
760 if (delta < 64) delta = 64;
761 if (delta % 2 != 0) delta++;
762 if (target % 2 != 0) target++;
763 do
764 {
765 delta <<= 1;
766 if (delta >= target)
767 {
768 delta = target;
769 jumpto(0);
770 for (int i = 0; i < numlines; i++)
771 {
772 loc[i] = locate();
773 getline(buff[i]);
774 }
775 break;
776 }
777 jumpto(target-delta);
778 do
779 {
780 getline(buff[0]);
781#ifdef WS
782 //printf("Trying:%s\n",buff[0]);
783#endif
784 if (locate() > target) continue;
785 }
786 while (!buffdoc.iseol());
787 for (int i = 0; i < numlines; i++)
788 {
789 loc[i] = locate();
790 getline(buff[i]);
791#ifdef WS
792 //printf("Filling:%s\n",buff[i]);
793#endif
794 }
795 }
796 while (locate() >= target && delta < 4096);
797#ifdef WS
798 //printf("Delta:%u\n",delta);
799#endif
800 }
801 else
802 {
803 jumpto(0);
804 for (int i = 0; i < numlines; i++)
805 {
806 loc[i] = locate();
807 getline(buff[i]);
808 }
809 }
810 cbptr = 0;
811 while (locate() < target)
812 {
813 loc[cbptr] = locate();
814 getline(buff[cbptr]);
815#ifdef WS
816 //printf("Adding:%s\n",buff[cbptr]->data());
817#endif
818 cbptr = (cbptr+1) % numlines;
819 }
820 pagepos = loc[cbptr];
821 textarray = new CBuffer*[numlines];
822 for (int i = 0; i < numlines; i++)
823 {
824 int j = (cbptr+i)%numlines;
825 textarray[i] = buff[j];
826 locnarray[i] = loc[j];
827 }
828 delete [] buff;
829 delete [] loc;
830 mylastpos = locate();
831 update();
832}
833
834bool QTReader::load_file(const char *newfile, unsigned int _lcn)
835{
836// QMessageBox::information(this, "Name", name, 1);
837// QMessageBox::information(this, "load_file", newfile, 1);
838
839 bool bRC = false;
840 unsigned int lcn = _lcn;
841 if (m_lastfile == newfile)
842 {
843 lcn = m_lastposn;
844 }
845 m_lastfile = newfile;
846 // QMessageBox::information(0, "Opening...", newfile);
847 if (buffdoc.openfile(this,newfile) == 0)
848 {
849 bRC = true;
850 // qDebug("buffdoc.openfile done");
851 locate(lcn);
852 // qDebug("buffdoc.locate done");
853 }
854 update();
855 // qDebug("Updated");
856 return bRC;
857}
858
859void QTReader::lineDown()
860{
861 pagepos = locnarray[1];
862 CBuffer* buff = textarray[0];
863 for (int i = 1; i < numlines; i++)
864 {
865 textarray[i-1] = textarray[i];
866 locnarray[i-1] = locnarray[i];
867 }
868 locnarray[numlines-1] = locate();
869 if (getline(buff))
870 {
871 textarray[numlines-1] = buff;
872 mylastpos = locate();
873 }
874 else
875 {
876 textarray[numlines-1] = buff;
877 }
878 update();
879}
880/*
881void QTReader::lineUp()
882{
883 CBuffer** buff = textarray;
884 unsigned int *loc = new unsigned int[numlines];
885 int cbptr = 0;
886 if (locate() != mylastpos) jumpto(mylastpos);
887 unsigned int target = locnarray[numlines-1];
888 if (buffdoc.hasrandomaccess())
889 {
890 unsigned int delta = locate()-pagelocate();
891 if (delta < 64) delta = 64;
892 do
893 {
894 delta <<= 1;
895 if (delta >= target)
896 {
897 delta = target;
898 jumpto(0);
899 for (int i = 0; i < numlines; i++)
900 {
901 loc[i] = locate();
902 getline(buff[i]);
903 }
904 break;
905 }
906 jumpto(target-delta);
907 do
908 {
909 buffdoc.getline(buff[0],width());
910#ifdef WS
911 //printf("Trying:%s\n",buff[0]);
912#endif
913 if (locate() > target) continue;
914 }
915 while (!buffdoc.iseol());
916 for (int i = 0; i < numlines; i++)
917 {
918 loc[i] = locate();
919 buffdoc.getline(buff[i],width());
920#ifdef WS
921 //printf("Filling:%s\n",buff[i]);
922#endif
923 }
924 }
925 while (locate() >= target && delta < 4096);
926#ifdef WS
927 //printf("Delta:%u\n",delta);
928#endif
929 }
930 else
931 {
932 jumpto(0);
933 for (int i = 0; i < numlines; i++)
934 {
935 loc[i] = locate();
936 buffdoc.getline(buff[i],width());
937 }
938 }
939 cbptr = 0;
940 while (locate() < target)
941 {
942 loc[cbptr] = locate();
943 buffdoc.getline(buff[cbptr], width());
944#ifdef WS
945 //printf("Adding:%s\n",buff[cbptr]->data());
946#endif
947 cbptr = (cbptr+1) % numlines;
948 }
949 pagepos = loc[cbptr];
950 textarray = new CBuffer*[numlines];
951 for (int i = 0; i < numlines; i++)
952 {
953 int j = (cbptr+i)%numlines;
954 textarray[i] = buff[j];
955 locnarray[i] = loc[j];
956 }
957 delete [] buff;
958 delete [] loc;
959 mylastpos = locate();
960 update();
961}
962*/
963void QTReader::lineUp()
964{
965 CBuffer* buff = textarray[numlines-1];
966 unsigned int loc;
967 unsigned int end = locnarray[numlines-1];
968 int cbptr = 0;
969 if (locate() != mylastpos) jumpto(mylastpos);
970 unsigned int target = locnarray[0];
971 if (buffdoc.hasrandomaccess())
972 {
973 unsigned int delta = locate()-pagelocate();
974 if (delta < 64) delta = 64;
975 do
976 {
977 delta <<= 1;
978 if (delta >= target)
979 {
980 delta = target;
981 jumpto(0);
982 for (int i = 0; i < numlines; i++)
983 {
984 loc = locate();
985 getline(buff);
986 }
987 break;
988 }
989 jumpto(target-delta);
990 do
991 {
992 getline(buff);
993#ifdef WS
994 //printf("Trying:%s\n",buff[0]);
995#endif
996 if (locate() > target) continue;
997 }
998 while (!buffdoc.iseol());
999 loc = locate();
1000 getline(buff);
1001 }
1002 while (locate() >= target && delta < 4096);
1003 }
1004 else
1005 {
1006 jumpto(0);
1007 loc = locate();
1008 getline(buff);
1009 }
1010 cbptr = 0;
1011 while (locate() < target)
1012 {
1013 loc = locate();
1014 getline(buff);
1015 }
1016 pagepos = loc;
1017 for (int i = numlines-1; i > 0; i--)
1018 {
1019 textarray[i] = textarray[i-1];
1020 locnarray[i] = locnarray[i-1];
1021 }
1022 textarray[0] = buff;
1023 locnarray[0] = loc;
1024// delete [] buff;
1025// delete [] loc;
1026 mylastpos = locate();
1027 jumpto(end);
1028 update();
1029}
1030
1031bool QTReader::empty()
1032{
1033 return buffdoc.empty();
1034}
diff --git a/noncore/apps/opie-reader/QTReader.h b/noncore/apps/opie-reader/QTReader.h
new file mode 100644
index 0000000..2efb988
--- a/dev/null
+++ b/noncore/apps/opie-reader/QTReader.h
@@ -0,0 +1,217 @@
1#ifndef __QTREADER_H
2#define __QTREADER_H
3
4#include <qwidget.h>
5#include <qpainter.h>
6#include <qclipboard.h>
7#include "CBuffer.h"
8#include "my_list.h"
9#include "BuffDoc.h"
10#include <qtimer.h>
11
12class QTReader : public QWidget
13{
14 Q_OBJECT
15
16 friend class QTReaderApp;
17 void drawText(QPainter& p, int x, int y, tchar* text);
18 int m_delay;
19 unsigned int m_overlap;
20 bool m_autoScroll;
21 void autoscroll();
22 QTimer* timer;
23 int m_scrolldy, m_encd;
24 void focusInEvent(QFocusEvent*);
25 void focusOutEvent(QFocusEvent*);
26 void ChangeFont(int);
27 bool getline(CBuffer*);
28 int m_charWidth;
29 int m_charpc;
30public:
31 QTReader( QWidget *parent=0, const char *name=0, WFlags f = 0);
32 // QTReader( const QString& filename, QWidget *parent=0, const tchar *name=0, WFlags f = 0);
33 ~QTReader();
34 bool empty();
35 void toggle_autoscroll();
36 void setautoscroll(bool);
37 void disableAutoscroll() { m_autoScroll = false; }
38 void copy()
39 {
40/*
41 size_t nd = locate();
42 jumpto(m_mark);
43 QString text;
44 while (m_mark < nd)
45 {
46 text += buffdoc.getch();
47 m_mark++;
48 }
49 QApplication::clipboard()->setText(text);
50 jumpto(nd);
51*/
52 };
53 void clear() {};
54 void setText(const QString& n, const QString& s) { m_string = n; load_file((const char*)s); };
55 /*
56 void setText(bool oldfile)
57 {
58 if (oldfile)
59 {
60 m_string = m_lastfile;
61 load_file((const tchar*)m_string);
62 }
63 else
64 {
65 m_string = QString::null;
66 }
67 };
68 */
69 void setstripcr(bool _b)
70 {
71 bstripcr = _b;
72 setfilter(getfilter());
73 }
74 void setstriphtml(bool _b)
75 {
76 bstriphtml = _b;
77 setfilter(getfilter());
78 }
79 void setdehyphen(bool _b)
80 {
81 bdehyphen = _b;
82 setfilter(getfilter());
83 }
84 void setunindent(bool _b)
85 {
86 bunindent = _b;
87 setfilter(getfilter());
88 }
89 void setrepara(bool _b)
90 {
91 brepara = _b;
92 setfilter(getfilter());
93 }
94 void setdblspce(bool _b)
95 {
96 bdblspce = _b;
97 setfilter(getfilter());
98 }
99 void indentplus()
100 {
101 if (bindenter < 15) bindenter += 2;
102 setfilter(getfilter());
103 }
104 void indentminus()
105 {
106 if (bindenter > 1) bindenter -= 2;
107 setfilter(getfilter());
108 }
109 void setpagemode(bool _b)
110 {
111 m_bpagemode = _b;
112 }
113 void setmono(bool _b)
114 {
115 m_bMonoSpaced = _b;
116 ChangeFont(fontsizes[m_textsize]);
117 locate(pagepos);
118 }
119 void setencoding(int _f)
120 {
121 m_encd = _f;
122 setfilter(getfilter());
123 }
124 CEncoding* getencoding()
125 {
126 switch (m_encd)
127 {
128 case 5:
129 return new Ccp1252;
130 case 4:
131 return new CPalm;
132 case 1:
133 return new CUtf8;
134 case 2:
135 return new CUcs16be;
136 case 3:
137 return new CUcs16le;
138 case 0:
139 default:
140 return new CAscii;
141 }
142 }
143 CFilterChain* getfilter()
144 {
145 CFilterChain * filt = new CFilterChain(getencoding());
146 if (bstripcr) filt->addfilter(new stripcr);
147 if (bstriphtml) filt->addfilter(new striphtml);
148 if (bdehyphen) filt->addfilter(new dehyphen);
149 if (bunindent) filt->addfilter(new unindent);
150 if (brepara) filt->addfilter(new repara);
151 if (bindenter) filt->addfilter(new indenter(bindenter));
152 if (bdblspce) filt->addfilter(new dblspce);
153 return filt;
154 }
155
156
157private slots:
158 void doscroll();
159 void drawIt( QPainter * );
160 void paintEvent( QPaintEvent * );
161// void resizeEvent( QResizeEvent * p ) { update(); }
162 void keyPressEvent(QKeyEvent*);
163 void drawFonts(QPainter*);
164 private:
165 void init();
166 void mouseReleaseEvent( QMouseEvent* );
167// void mouseDoubleClickEvent( QMouseEvent* );
168 QString m_string, m_fontname;
169 void setfont(QPainter*);
170 //myoutput stuff
171 private:
172 void dopageup();
173 void lineDown();
174 void lineUp();
175 void dopagedn();
176 long real_delay();
177 int m_textsize;
178 int m_lastwidth;
179 CBuffer** textarray;
180 size_t* locnarray;
181 unsigned int numlines;
182 bool bstripcr, bstriphtml, bdehyphen, bunindent, brepara, bdblspce, btight, m_bBold;
183 bool m_bpagemode, m_bMonoSpaced;
184 QString m_targetapp, m_targetmsg;
185 unsigned char bindenter;
186 QString m_lastfile;
187 size_t m_lastposn;
188 public:
189 int getch() { return buffdoc.getch(); }
190 bool tight;
191 bool load_file(const char *newfile, unsigned int lcn=0);
192 BuffDoc buffdoc;
193 CList<Bkmk>* getbkmklist() { return buffdoc.getbkmklist(); }
194 bool locate(unsigned long n);
195 void jumpto(unsigned long n) { buffdoc.locate(n); }
196 unsigned long locate() { return buffdoc.locate(); }
197 unsigned long pagelocate() { return pagepos; }
198 unsigned long pagepos, mylastpos;
199 void setfilter(CFilterChain *f) { buffdoc.setfilter(f); locate(pagepos); }
200 void restore() { jumpto(mylastpos); }
201 void goUp();
202 void refresh() { locate(pagepos); }
203 void goDown();
204 // bool bold;
205 int textsize() { return m_textsize; }
206 void textsize(int ts) { m_textsize = ts; }
207 bool fillbuffer();
208 unsigned int screenlines();
209 void sizes(unsigned long& fs, unsigned long& ts) { buffdoc.sizes(fs,ts); }
210 static const char *fonts[];
211 unsigned int *fontsizes;
212 int m_ascent, m_descent, m_linespacing;
213 QFontMetrics* m_fm;
214 QString firstword();
215};
216
217#endif
diff --git a/noncore/apps/opie-reader/QTReaderApp.cpp b/noncore/apps/opie-reader/QTReaderApp.cpp
new file mode 100644
index 0000000..620e93e
--- a/dev/null
+++ b/noncore/apps/opie-reader/QTReaderApp.cpp
@@ -0,0 +1,1433 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qwidgetstack.h>
22#include <qpe/qpemenubar.h>
23#include <qpe/qpetoolbar.h>
24#include <qpe/fontdatabase.h>
25#include <qcombobox.h>
26#include <qpopupmenu.h>
27#include <qaction.h>
28#include <qapplication.h>
29#include <qlineedit.h>
30#include <qtoolbutton.h>
31#include <qspinbox.h>
32#include <qobjectlist.h>
33#include <qpe/global.h>
34#include <qpe/applnk.h>
35#include <qfileinfo.h>
36#include <stdlib.h> //getenv
37#include <qprogressbar.h>
38#include <qpe/config.h>
39#include <qbuttongroup.h>
40#include <qradiobutton.h>
41
42#include "cbkmkselector.h"
43#include "infowin.h"
44
45//#include <qpe/fontdatabase.h>
46
47#include <qpe/resource.h>
48#include <qpe/qpeapplication.h>
49
50#include "QTReaderApp.h"
51#include "fileBrowser.h"
52
53
54unsigned long QTReaderApp::m_uid = 0;
55
56void QTReaderApp::setScrollState(bool _b) { m_scrollButton->setOn(_b); }
57
58#include <unistd.h>
59#include <stddef.h>
60#include <dirent.h>
61
62void QTReaderApp::listBkmkFiles()
63{
64 bkmkselector->clear();
65 int cnt = 0;
66 DIR *d;
67 d = opendir((const char *)Global::applicationFileName("uqtreader",""));
68
69 while(1)
70 {
71 struct dirent* de;
72 struct stat buf;
73 de = readdir(d);
74 if (de == NULL) break;
75
76 if (lstat((const char *)Global::applicationFileName("uqtreader",de->d_name),&buf) == 0 && S_ISREG(buf.st_mode))
77 {
78 bkmkselector->insertItem(de->d_name);
79 cnt++;
80 }
81 }
82
83 closedir(d);
84
85 if (cnt > 0)
86 {
87 menu->hide();
88 editBar->hide();
89 if (m_fontVisible) m_fontBar->hide();
90 if (regVisible) regBar->hide();
91 if (searchVisible) searchBar->hide();
92 m_nRegAction = cRmBkmkFile;
93 editorStack->raiseWidget( bkmkselector );
94 }
95 else
96 QMessageBox::information(this, "QTReader", "No bookmark files");
97}
98
99QTReaderApp::QTReaderApp( QWidget *parent, const char *name, WFlags f )
100 : QMainWindow( parent, name, f ), bFromDocView( FALSE )
101{
102// qDebug("Application directory = %s", (const tchar *)QPEApplication::documentDir());
103// qDebug("Application directory = %s", (const tchar *)Global::applicationFileName("uqtreader","bkmks.xml"));
104
105 pBkmklist = NULL;
106 doc = 0;
107
108 m_fBkmksChanged = false;
109
110 QString lang = getenv( "LANG" );
111
112 m_autogenstr = "^ *[A-Z].*[a-z] *$";
113 setToolBarsMovable( FALSE );
114
115 setIcon( Resource::loadPixmap( "uqtreader" ) );
116
117 QPEToolBar *bar = new QPEToolBar( this );
118 bar->setHorizontalStretchable( TRUE );
119 addToolBar(bar, "tool",QMainWindow::Top, true);
120 menu = bar;
121
122 QPEMenuBar *mb = new QPEMenuBar( bar );
123 QPopupMenu *file = new QPopupMenu( this );
124 QPopupMenu *format = new QPopupMenu( this );
125 // QPopupMenu *edit = new QPopupMenu( this );
126
127// bar = new QToolBar( this );
128 editBar = bar;
129
130 /*
131 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 );
132 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
133 a->addTo( bar );
134 a->addTo( file );
135 */
136
137 editorStack = new QWidgetStack( this );
138 setCentralWidget( editorStack );
139
140 searchVisible = FALSE;
141 regVisible = FALSE;
142 m_fontVisible = false;
143
144 pbar = new QProgressBar(this);
145 pbar->hide();
146
147 m_infoWin = new infowin(editorStack);
148 editorStack->addWidget(m_infoWin, get_unique_id());
149 connect( m_infoWin, SIGNAL( Close() ), this, SLOT( infoClose() ) );
150
151// bkmkselector = new QListBox(editorStack, "Bookmarks");
152 bkmkselector = new CBkmkSelector(editorStack, "Bookmarks");
153 // connect(bkmkselector, SIGNAL( selected(const QString&) ), this, SLOT( gotobkmk(const QString&) ) );
154 connect(bkmkselector, SIGNAL( selected(int) ), this, SLOT( gotobkmk(int) ) );
155 connect(bkmkselector, SIGNAL( cancelled() ), this, SLOT( cancelbkmk() ) );
156 editorStack->addWidget( bkmkselector, get_unique_id() );
157
158/*
159 importSelector = new FileSelector( "*", editorStack, "importselector", false );
160 connect( importSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( importFile( const DocLnk & ) ) );
161
162 editorStack->addWidget( importSelector, get_unique_id() );
163
164 // don't need the close visible, it is redundant...
165 importSelector->setCloseVisible( FALSE );
166*/
167
168 reader = new QTReader( editorStack );
169 Config config( "uqtreader" );
170 config.setGroup( "View" );
171
172 reader->bstripcr = config.readBoolEntry( "StripCr", true );
173 reader->bstriphtml = config.readBoolEntry( "StripHtml", false );
174 reader->bdehyphen = config.readBoolEntry( "Dehyphen", false );
175 reader->bunindent = config.readBoolEntry( "Unindent", false );
176 reader->brepara = config.readBoolEntry( "Repara", false );
177 reader->bdblspce = config.readBoolEntry( "DoubleSpace", false );
178 reader->bindenter = config.readNumEntry( "Indent", 0 );
179 reader->m_textsize = config.readNumEntry( "FontSize", 12 );
180 reader->m_bBold = config.readBoolEntry( "Bold", false );
181 reader->m_delay = config.readNumEntry( "ScrollDelay", 5184);
182 reader->m_lastfile = config.readEntry( "LastFile", QString::null );
183 reader->m_lastposn = config.readNumEntry( "LastPosn", 0 );
184 reader->m_bpagemode = config.readBoolEntry( "PageMode", true );
185 reader->m_bMonoSpaced = config.readBoolEntry( "MonoSpaced", false);
186 reader->m_fontname = config.readEntry( "Fontname", "helvetica" );
187 reader->m_encd = config.readNumEntry( "Encoding", 0 );
188 reader->m_charpc = config.readNumEntry( "CharSpacing", 100 );
189 reader->m_overlap = config.readNumEntry( "Overlap", 0 );
190 reader->m_targetapp = config.readEntry( "TargetApp", QString::null );
191 reader->m_targetmsg = config.readEntry( "TargetMsg", QString::null );
192 reader->init();
193 editorStack->addWidget( reader, get_unique_id() );
194
195 QAction *a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
196 connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
197 a->addTo( bar );
198 a->addTo( file );
199
200 /*
201 a = new QAction( tr( "Revert" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
202 connect( a, SIGNAL( activated() ), this, SLOT( fileRevert() ) );
203 a->addTo( file );
204
205 a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
206 connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
207 a->addTo( editBar );
208 a->addTo( edit );
209 */
210
211 a = new QAction( tr( "Info" ), QString::null, 0, this, NULL);
212 connect( a, SIGNAL( activated() ), this, SLOT( showinfo() ) );
213 a->addTo( file );
214
215 a = new QAction( tr( "Start Block" ), QString::null, 0, this, NULL);
216 connect( a, SIGNAL( activated() ), this, SLOT( editMark() ) );
217 file->insertSeparator();
218 a->addTo( file );
219
220 a = new QAction( tr( "Copy Block" ), QString::null, 0, this, NULL);
221 connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
222 a->addTo( file );
223
224 a = m_scrollButton = new QAction( tr( "Scroll" ), Resource::loadPixmap( "panel-arrow-down" ), QString::null, 0, this, 0, true );
225// connect( a, SIGNAL( activated() ), this, SLOT( autoScroll() ) );
226 a->setOn(false);
227 connect( a, SIGNAL( toggled(bool) ), this, SLOT( autoScroll(bool) ) );
228 file->insertSeparator();
229 a->addTo( bar );
230 a->addTo( file );
231
232 /*
233 a = new QAction( tr( "Find" ), QString::null, 0, this, NULL, true );
234 // connect( a, SIGNAL( activated() ), this, SLOT( pagedn() ) );
235 a->addTo( file );
236
237 a = new QAction( tr( "Find Again" ), QString::null, 0, this, NULL, true );
238 // connect( a, SIGNAL( activated() ), this, SLOT( pagedn() ) );
239 a->addTo( file );
240 */
241 a = new QAction( tr( "Jump" ), QString::null, 0, this, NULL);
242 connect( a, SIGNAL( activated() ), this, SLOT( jump() ) );
243 a->addTo( file );
244
245 a = new QAction( tr( "Page/Line scroll" ), QString::null, 0, this, NULL, true );
246 connect( a, SIGNAL( toggled(bool) ), this, SLOT( pagemode(bool) ) );
247 a->setOn(reader->m_bpagemode);
248 a->addTo( file );
249
250 a = new QAction( tr( "Set Overlap" ), QString::null, 0, this, NULL);
251 connect( a, SIGNAL( activated() ), this, SLOT( setoverlap() ) );
252 a->addTo( file );
253
254 a = new QAction( tr( "Set Dictionary" ), QString::null, 0, this, NULL);
255 connect( a, SIGNAL( activated() ), this, SLOT( settarget() ) );
256 a->addTo( file );
257
258/*
259 a = new QAction( tr( "Import" ), QString::null, 0, this, NULL );
260 connect( a, SIGNAL( activated() ), this, SLOT( importFiles() ) );
261 a->addTo( file );
262*/
263
264 a = new QAction( tr( "Up" ), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
265 connect( a, SIGNAL( activated() ), this, SLOT( pageup() ) );
266 a->addTo( editBar );
267
268 a = new QAction( tr( "Down" ), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
269 connect( a, SIGNAL( activated() ), this, SLOT( pagedn() ) );
270 a->addTo( editBar );
271
272 /*
273 a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
274 connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
275 a->addTo( editBar );
276 a->addTo( edit );
277 */
278
279 a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 );
280 connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) );
281 file->insertSeparator();
282 a->addTo( bar );
283 a->addTo( file );
284
285
286 a = new QAction( tr( "Strip CR" ), QString::null, 0, this, NULL, true );
287 a->setOn(reader->bstripcr);
288 connect( a, SIGNAL( toggled(bool) ), this, SLOT( stripcr(bool) ) );
289 a->addTo( format );
290 // a->setOn(true);
291
292 a = new QAction( tr( "Strip HTML" ), QString::null, 0, this, NULL, true );
293 a->setOn(reader->bstriphtml);
294 connect( a, SIGNAL( toggled(bool) ), this, SLOT( striphtml(bool) ) );
295 a->addTo( format );
296
297 a = new QAction( tr( "Dehyphen" ), QString::null, 0, this, NULL, true );
298 a->setOn(reader->bdehyphen);
299 connect( a, SIGNAL( toggled(bool) ), this, SLOT( dehyphen(bool) ) );
300 a->addTo( format );
301
302 a = new QAction( tr( "Unindent" ), QString::null, 0, this, NULL, true );
303 connect( a, SIGNAL( toggled(bool) ), this, SLOT( unindent(bool) ) );
304 a->setOn(reader->bunindent);
305 a->addTo( format );
306
307 a = new QAction( tr( "Re-paragraph" ), QString::null, 0, this, NULL, true );
308 connect( a, SIGNAL( toggled(bool) ), this, SLOT( repara(bool) ) );
309 a->setOn(reader->brepara);
310 a->addTo( format );
311
312 a = new QAction( tr( "Double Space" ), QString::null, 0, this, NULL, true );
313 connect( a, SIGNAL( toggled(bool) ), this, SLOT( dblspce(bool) ) );
314 a->setOn(reader->bdblspce);
315 a->addTo( format );
316
317 a = new QAction( tr( "Indent+" ), QString::null, 0, this, NULL );
318 connect( a, SIGNAL( activated() ), this, SLOT( indentplus() ) );
319 a->addTo( format );
320
321 a = new QAction( tr( "Indent-" ), QString::null, 0, this, NULL );
322 connect( a, SIGNAL( activated() ), this, SLOT( indentminus() ) );
323 a->addTo( format );
324
325 a = new QAction( tr( "Bold" ), QString::null, 0, this, NULL, true );
326 a->setOn(reader->m_bBold);
327 connect( a, SIGNAL( toggled(bool) ), this, SLOT( setbold(bool) ) );
328 a->addTo( format );
329
330 // a = new QAction( tr( "Zoom" ), QString::null, 0, this, NULL, true );
331 // a = new QAction( tr( "Zoom" ), Resource::loadPixmap( "mag" ), QString::null, 0, this, 0 );
332 a = new QAction( tr( "Zoom" ), QString::null, 0, this);
333 connect( a, SIGNAL( activated() ), this, SLOT( TBDzoom() ) );
334 format->insertSeparator();
335 a->addTo( format );
336 // a->addTo( editBar );
337
338
339 a = new QAction( tr( "Ideogram/Word" ), QString::null, 0, this, NULL, true );
340 connect( a, SIGNAL( toggled(bool) ), this, SLOT( monospace(bool) ) );
341 a->setOn(reader->m_bMonoSpaced);
342 format->insertSeparator();
343 a->addTo( format );
344
345 a = new QAction( tr( "Set width" ), QString::null, 0, this, NULL);
346 connect( a, SIGNAL( activated() ), this, SLOT( setspacing() ) );
347 a->addTo( format );
348
349 QPopupMenu *encoding = new QPopupMenu(this);
350 format->insertSeparator();
351 format->insertItem( tr( "Encoding" ), encoding );
352
353 QActionGroup* ag = new QActionGroup(this);
354
355 m_EncodingAction[0] = new QAction( tr( "Ascii" ), QString::null, 0, ag, NULL, true );
356
357 m_EncodingAction[1] = new QAction( tr( "UTF-8" ), QString::null, 0, ag, NULL, true );
358
359 m_EncodingAction[2] = new QAction( tr( "UCS-2(BE)" ), QString::null, 0, ag, NULL, true );
360
361 m_EncodingAction[3] = new QAction( tr( "USC-2(LE)" ), QString::null, 0, ag, NULL, true );
362
363 m_EncodingAction[4] = new QAction( tr( "Palm" ), QString::null, 0, ag, NULL, true );
364
365 m_EncodingAction[5] = new QAction( tr( "Windows(1252)" ), QString::null, 0, ag, NULL, true );
366
367 ag->addTo(encoding);
368
369 connect(ag, SIGNAL( selected(QAction*) ), this, SLOT( encodingSelected(QAction*) ) );
370
371 a = new QAction( tr( "Set Font" ), QString::null, 0, this);
372 connect( a, SIGNAL( activated() ), this, SLOT( setfont() ) );
373 format->insertSeparator();
374 a->addTo( format );
375
376 QPopupMenu *marks = new QPopupMenu( this );
377
378 a = new QAction( tr( "Mark" ), QString::null, 0, this, NULL);
379 connect( a, SIGNAL( activated() ), this, SLOT( addbkmk() ) );
380 a->addTo( marks );
381
382 a = new QAction( tr( "Goto" ), QString::null, 0, this, NULL, false );
383 connect( a, SIGNAL( activated() ), this, SLOT( do_gotomark() ) );
384 a->addTo( marks );
385
386 a = new QAction( tr( "Delete" ), QString::null, 0, this, NULL);
387 connect( a, SIGNAL( activated() ), this, SLOT( do_delmark() ) );
388 a->addTo( marks );
389
390 a = new QAction( tr( "Autogen" ), QString::null, 0, this, NULL, false );
391 connect( a, SIGNAL( activated() ), this, SLOT( do_autogen() ) );
392 marks->insertSeparator();
393 a->addTo( marks );
394
395 a = new QAction( tr( "Clear" ), QString::null, 0, this, NULL);
396 connect( a, SIGNAL( activated() ), this, SLOT( clearBkmkList() ) );
397 a->addTo( marks );
398
399 a = new QAction( tr( "Save" ), QString::null, 0, this, NULL );
400 connect( a, SIGNAL( activated() ), this, SLOT( savebkmks() ) );
401 a->addTo( marks );
402
403 a = new QAction( tr( "Tidy" ), QString::null, 0, this, NULL);
404 connect( a, SIGNAL( activated() ), this, SLOT( listBkmkFiles() ) );
405 marks->insertSeparator();
406 a->addTo( marks );
407
408 mb->insertItem( tr( "File" ), file );
409 // mb->insertItem( tr( "Edit" ), edit );
410 mb->insertItem( tr( "Format" ), format );
411 mb->insertItem( tr( "Marks" ), marks );
412
413 searchBar = new QToolBar( "Search", this, QMainWindow::Top, TRUE );
414
415 searchBar->setHorizontalStretchable( TRUE );
416
417 searchEdit = new QLineEdit( searchBar, "searchEdit" );
418// QFont f("unifont", 16 /*, QFont::Bold*/);
419// searchEdit->setFont( f );
420 searchBar->setStretchableWidget( searchEdit );
421#ifdef __ISEARCH
422 connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
423 this, SLOT( search( const QString& ) ) );
424#else
425 connect( searchEdit, SIGNAL( returnPressed( ) ),
426 this, SLOT( search( ) ) );
427#endif
428 a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 );
429 connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) );
430 a->addTo( searchBar );
431
432 a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
433 connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) );
434 a->addTo( searchBar );
435
436 searchBar->hide();
437
438 regBar = new QToolBar( "Autogen", this, QMainWindow::Top, TRUE );
439
440 regBar->setHorizontalStretchable( TRUE );
441
442 regEdit = new QLineEdit( regBar, "regEdit" );
443// regEdit->setFont( f );
444
445 regBar->setStretchableWidget( regEdit );
446
447 connect( regEdit, SIGNAL( returnPressed( ) ),
448 this, SLOT( do_regaction() ) );
449
450 a = new QAction( tr( "Do Reg" ), Resource::loadPixmap( "enter" ), QString::null, 0, this, 0 );
451 connect( a, SIGNAL( activated() ), this, SLOT( do_regaction() ) );
452 a->addTo( regBar );
453
454 a = new QAction( tr( "Close Edit" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
455 connect( a, SIGNAL( activated() ), this, SLOT( regClose() ) );
456 a->addTo( regBar );
457
458 regBar->hide();
459
460 m_fontBar = new QToolBar( "Autogen", this, QMainWindow::Top, TRUE );
461
462 m_fontBar->setHorizontalStretchable( TRUE );
463
464 m_fontSelector = new QComboBox(false, m_fontBar);
465 m_fontBar->setStretchableWidget( m_fontSelector );
466 {
467 FontDatabase f;
468 m_fontSelector->insertStringList(f.families());
469 } // delete the FontDatabase!!!
470 connect( m_fontSelector, SIGNAL( activated(const QString& ) ),
471 this, SLOT( do_setfont(const QString&) ) );
472
473 m_fontBar->hide();
474 m_fontVisible = false;
475
476 connect(qApp, SIGNAL( appMessage(const QCString&, const QByteArray& ) ),
477 this, SLOT( msgHandler(const QCString&, const QByteArray&) ) );
478
479
480 if (!reader->m_lastfile.isEmpty())
481 {
482 openFile( reader->m_lastfile );
483 doc = new DocLnk(reader->m_lastfile);
484 }
485 m_EncodingAction[reader->m_encd]->setOn(true);
486 do_setfont(reader->m_fontname);
487}
488
489void QTReaderApp::msgHandler(const QCString& _msg, const QByteArray& _data)
490{
491 QString msg = QString::fromUtf8(_msg);
492
493// qDebug("Received:%s", (const char*)msg);
494
495 QDataStream stream( _data, IO_ReadOnly );
496 if ( msg == "info(QString)" )
497 {
498 QString info;
499 stream >> info;
500 QMessageBox::information(this, "QTReader", info);
501 } else if ( msg == "warn(QString)" )
502 {
503 QString info;
504 stream >> info;
505 QMessageBox::warning(this, "QTReader", info);
506 }
507}
508
509int QTReaderApp::EncNameToInt(const QString& _enc)
510{
511 for (int i = 0; i < MAX_ENCODING; i++)
512 {
513 if (m_EncodingAction[i]->text() == _enc) return i;
514 }
515 return 0;
516/*
517 if (_enc == "Ascii") return 0;
518 if (_enc == "UTF-8") return 1;
519 if (_enc == "UCS-2(BE)") return 2;
520 if (_enc == "USC-2(LE)") return 3;
521*/
522}
523
524void QTReaderApp::encodingSelected(QAction* _a)
525{
526// qDebug("es:%x : %s", _a, (const char *)(_a->text()));
527 reader->setencoding(EncNameToInt(_a->text()));
528}
529
530QTReaderApp::~QTReaderApp()
531{
532}
533
534void QTReaderApp::autoScroll(bool _b)
535{
536 reader->setautoscroll(_b);
537}
538
539void QTReaderApp::TBD()
540{
541 QMessageBox::information(this, "QTReader", "Not yet implemented", 1);
542}
543
544void QTReaderApp::TBDzoom()
545{
546 QMessageBox::information(this, "QTReader", "Zooming is done interactively\nTry left/right cursor keys", 1);
547}
548
549void QTReaderApp::clearBkmkList()
550{
551 delete pBkmklist;
552 pBkmklist = NULL;
553 m_fBkmksChanged = false;
554}
555
556void QTReaderApp::fileOpen()
557{
558/*
559 menu->hide();
560 editBar->hide();
561 if (regVisible) regBar->hide();
562 if (searchVisible) searchBar->hide();
563*/
564 if (pBkmklist != NULL)
565 {
566 if (m_fBkmksChanged)
567 {
568 if (QMessageBox::warning(this, "QTReader", "Save bookmarks?", "Save", "Don't bother") == 0)
569 savebkmks();
570 }
571 delete pBkmklist;
572 pBkmklist = NULL;
573 m_fBkmksChanged = false;
574 }
575 reader->disableAutoscroll();
576/*
577 editorStack->raiseWidget( fileSelector );
578 fileSelector->reread();
579*/
580 fileBrowser* fb = new fileBrowser(this,"QTReader",TRUE,
581 0,
582 // WStyle_Customize | WStyle_NoBorderEx,
583 "*", QFileInfo(reader->m_lastfile).dirPath(true));
584
585 if (fb->exec())
586 {
587 QString fn(fb->fileList[0]);
588// fb->populateList();
589 if (!fn.isEmpty() && QFileInfo(fn).isFile()) openFile(fn);
590 }
591 delete fb;
592}
593
594void QTReaderApp::showinfo()
595{
596 unsigned long fs, ts, pl;
597 if (reader->empty())
598 {
599 QMessageBox::information(this, "QTReader", "No file loaded", 1);
600 }
601 else
602 {
603 reader->sizes(fs,ts);
604 pl = reader->pagelocate();
605 m_infoWin->setFileSize(fs);
606 m_infoWin->setTextSize(ts);
607 m_infoWin->setRatio(100-(100*fs + (ts >> 1))/ts);
608 m_infoWin->setLocation(pl);
609 m_infoWin->setRead((100*pl + (ts >> 1))/ts);
610 editorStack->raiseWidget( m_infoWin );
611 m_infoWin->setFocus();
612 }
613}
614
615void QTReaderApp::infoClose()
616{
617 showEditTools();
618}
619
620/*
621void QTReaderApp::fileRevert()
622{
623 clear();
624 fileOpen();
625}
626
627void QTReaderApp::editCut()
628{
629#ifndef QT_NO_CLIPBOARD
630 editor->cut();
631#endif
632}
633*/
634void QTReaderApp::editMark()
635{
636 m_savedpos = reader->pagelocate();
637}
638
639void QTReaderApp::editCopy()
640{
641 QClipboard* cb = QApplication::clipboard();
642 QString text;
643 int ch;
644 unsigned long currentpos = reader->pagelocate();
645 unsigned long endpos = reader->locate();
646 reader->jumpto(m_savedpos);
647 while (reader->locate() < endpos && (ch = reader->getch()) != UEOF)
648 {
649 text += ch;
650 }
651 cb->setText(text);
652 //text = cb->text();
653 //if (text)
654 // qDebug("The clipboard contains: %s", (const tchar*)text);
655 reader->locate(currentpos);
656#ifndef QT_NO_CLIPBOARD
657// TBD();
658 // reader->copy();
659#endif
660}
661
662void QTReaderApp::pageup()
663{
664 reader->goUp();
665}
666
667void QTReaderApp::pagedn()
668{
669 reader->goDown();
670}
671
672void QTReaderApp::stripcr(bool _b)
673{
674 reader->setstripcr(_b);
675}
676void QTReaderApp::striphtml(bool _b)
677{
678 reader->setstriphtml(_b);
679}
680void QTReaderApp::dehyphen(bool _b)
681{
682 reader->setdehyphen(_b);
683}
684void QTReaderApp::unindent(bool _b)
685{
686 reader->setunindent(_b);
687}
688void QTReaderApp::repara(bool _b)
689{
690 reader->setrepara(_b);
691}
692void QTReaderApp::setbold(bool _b)
693{
694 reader->m_bBold = _b;
695 reader->ChangeFont(reader->fontsizes[reader->m_textsize]);
696 reader->refresh();
697}
698void QTReaderApp::dblspce(bool _b)
699{
700 reader->setdblspce(_b);
701}
702void QTReaderApp::pagemode(bool _b)
703{
704 reader->setpagemode(_b);
705}
706
707void QTReaderApp::monospace(bool _b)
708{
709 reader->setmono(_b);
710}
711
712void QTReaderApp::setspacing()
713{
714 m_nRegAction = cMonoSpace;
715 char lcn[20];
716 sprintf(lcn, "%lu", reader->m_charpc);
717 regEdit->setText(lcn);
718 do_regedit();
719}
720
721void QTReaderApp::setoverlap()
722{
723 m_nRegAction = cOverlap;
724 char lcn[20];
725 sprintf(lcn, "%lu", reader->m_overlap);
726 regEdit->setText(lcn);
727 do_regedit();
728}
729
730void QTReaderApp::settarget()
731{
732 m_nRegAction = cSetTarget;
733 QString text = ((reader->m_targetapp.isEmpty()) ? QString("") : reader->m_targetapp)
734 + "/"
735 + ((reader->m_targetmsg.isEmpty()) ? QString("") : reader->m_targetmsg);
736 regEdit->setText(text);
737 do_regedit();
738}
739
740void QTReaderApp::do_overlap(const QString& lcn)
741{
742 bool ok;
743 unsigned long ulcn = lcn.toULong(&ok);
744 if (ok)
745 {
746 reader->m_overlap = ulcn;
747 }
748 else
749 QMessageBox::information(this, "QTReader", "Must be a number");
750}
751
752void QTReaderApp::do_mono(const QString& lcn)
753{
754 bool ok;
755 unsigned long ulcn = lcn.toULong(&ok);
756 if (ok)
757 {
758 reader->m_charpc = ulcn;
759 //reader->setmono(true);
760 }
761 else
762 QMessageBox::information(this, "QTReader", "Must be a number");
763}
764
765/*
766void QTReaderApp::editPaste()
767{
768#ifndef QT_NO_CLIPBOARD
769 editor->paste();
770#endif
771}
772*/
773
774void QTReaderApp::editFind()
775{
776 searchStart = reader->pagelocate();
777#ifdef __ISEARCH
778 searchStack = new QStack<searchrecord>;
779#endif
780 searchBar->show();
781 searchVisible = TRUE;
782 searchEdit->setFocus();
783#ifdef __ISEARCH
784 searchStack->push(new searchrecord("",reader->pagelocate()));
785#endif
786}
787
788void QTReaderApp::findNext()
789{
790 // qDebug("findNext called\n");
791#ifdef __ISEARCH
792 QString arg = searchEdit->text();
793#else
794 QRegExp arg = searchEdit->text();
795#endif
796 CBuffer test;
797 size_t start = reader->pagelocate();
798 reader->jumpto(start);
799 reader->buffdoc.getline(&test,reader->width());
800 dosearch(start, test, arg);
801}
802
803void QTReaderApp::findClose()
804{
805 searchVisible = FALSE;
806 searchEdit->setText("");
807 searchBar->hide();
808#ifdef __ISEARCH
809// searchStack = new QStack<searchrecord>;
810 while (!searchStack->isEmpty())
811 {
812 delete searchStack->pop();
813 }
814 delete searchStack;
815#endif
816 reader->setFocus();
817}
818
819void QTReaderApp::regClose()
820{
821 regVisible = FALSE;
822 regEdit->setText("");
823 regBar->hide();
824 reader->setFocus();
825}
826
827#ifdef __ISEARCH
828bool QTReaderApp::dosearch(size_t start, CBuffer& test, const QString& arg)
829#else
830bool QTReaderApp::dosearch(size_t start, CBuffer& test, const QRegExp& arg)
831#endif
832{
833 bool ret = true;
834 size_t pos = start;
835 reader->buffdoc.getline(&test,reader->width());
836#ifdef __ISEARCH
837 while (strstr(test.data(),(const tchar*)arg) == NULL)
838#else
839#ifdef _UNICODE
840 while (arg.match(toQString(test.data())) == -1)
841#else
842 while (arg.match(test.data()) == -1)
843#endif
844#endif
845 {
846 pos = reader->locate();
847 if (!reader->buffdoc.getline(&test,reader->width()))
848 {
849 if (QMessageBox::warning(this, "Can't find", searchEdit->text(), 1, 2) == 2)
850 pos = searchStart;
851 else
852 pos = start;
853 ret = false;
854 findClose();
855 break;
856 }
857 }
858 reader->locate(pos);
859 return ret;
860}
861
862#ifdef __ISEARCH
863void QTReaderApp::search(const QString & arg)
864{
865 searchrecord* ss = searchStack->top();
866 CBuffer test;
867 size_t start = reader->pagelocate();
868 bool haspopped = false;
869 while (arg.left(ss->s.length()) != ss->s)
870 {
871 haspopped = true;
872 start = ss->pos;
873// reader->locate(start);
874 searchStack->pop();
875 delete ss;
876 }
877 if (haspopped) reader->locate(start);
878/*
879 if (arg.length() < ss->len)
880 {
881 start = ss->pos;
882 reader->locate(start);
883 searchStack->pop();
884 delete ss;
885 }
886*/
887 else
888 {
889 start = reader->pagelocate();
890 reader->jumpto(start);
891 searchStack->push(new searchrecord(arg,start));
892 }
893 dosearch(start, test, arg);
894}
895#else
896void QTReaderApp::search()
897{
898 QRegExp arg = searchEdit->text();
899 CBuffer test;
900 size_t start = reader->pagelocate();
901// reader->jumpto(start);
902 dosearch(start, test, arg);
903}
904#endif
905
906void QTReaderApp::openFile( const QString &f )
907{
908 openFile(DocLnk(f));
909}
910
911void QTReaderApp::openFile( const DocLnk &f )
912{
913 clear();
914 FileManager fm;
915 if ( fm.exists( f ) )
916 {
917// QMessageBox::information(0, "Progress", "Calling fileNew()");
918
919 clear();
920
921 // editorStack->raiseWidget( reader );
922
923 // reader->setFocus();
924
925 // QMessageBox::information(0, "DocLnk", "Begin");
926 doc = new DocLnk(f);
927 // QMessageBox::information(0, "DocLnk done", doc->file());
928 // QMessageBox::information(0, "Progress", "Calling setText()");
929 // QMessageBox::information(0, "Progress", "Textset");
930
931 // updateCaption();
932 showEditTools();
933 reader->setText(doc->name(), doc->file());
934 readbkmks();
935 }
936 else
937 {
938 QMessageBox::information(this, "QTReader", "File does not exist");
939 }
940
941}
942
943void QTReaderApp::showEditTools()
944{
945 if ( !doc )
946 close();
947// fileSelector->hide();
948 menu->show();
949 editBar->show();
950 if ( searchVisible )
951 searchBar->show();
952 if ( regVisible )
953 regBar->show();
954 if (m_fontVisible) m_fontBar->show();
955
956 updateCaption();
957 editorStack->raiseWidget( reader );
958 reader->setFocus();
959}
960/*
961void QTReaderApp::save()
962{
963 if ( !doc )
964 return;
965 if ( !editor->edited() )
966 return;
967
968 QString rt = editor->text();
969 QString pt = rt;
970
971 if ( doc->name().isEmpty() ) {
972 unsigned ispace = pt.find( ' ' );
973 unsigned ienter = pt.find( '\n' );
974 int i = (ispace < ienter) ? ispace : ienter;
975 QString docname;
976 if ( i == -1 ) {
977 if ( pt.isEmpty() )
978 docname = "Empty Text";
979 else
980 docname = pt;
981 } else {
982 docname = pt.left( i );
983 }
984 doc->setName(docname);
985 }
986 FileManager fm;
987 fm.saveFile( *doc, rt );
988}
989*/
990
991void QTReaderApp::clear()
992{
993 if (doc != 0)
994 {
995// QMessageBox::information(this, "QTReader", "Deleting doc", 1);
996 delete doc;
997// QMessageBox::information(this, "QTReader", "Deleted doc", 1);
998 doc = 0;
999 }
1000 reader->clear();
1001}
1002
1003void QTReaderApp::updateCaption()
1004{
1005 if ( !doc )
1006 setCaption( tr("QTReader") );
1007 else {
1008 QString s = doc->name();
1009 if ( s.isEmpty() )
1010 s = tr( "Unnamed" );
1011 setCaption( s + " - " + tr("QTReader") );
1012 }
1013}
1014
1015void QTReaderApp::setDocument(const QString& fileref)
1016{
1017 bFromDocView = TRUE;
1018//QMessageBox::information(0, "setDocument", fileref);
1019 openFile(DocLnk(fileref));
1020// showEditTools();
1021}
1022
1023void QTReaderApp::closeEvent( QCloseEvent *e )
1024{
1025 if (editorStack->visibleWidget() == reader)
1026 {
1027 if (m_fontVisible)
1028 {
1029 m_fontBar->hide();
1030 m_fontVisible = false;
1031 }
1032 if (regVisible)
1033 {
1034 regBar->hide();
1035 regVisible = false;
1036 return;
1037 }
1038 if (searchVisible)
1039 {
1040 searchBar->hide();
1041 searchVisible = false;
1042 return;
1043 }
1044 if (m_fBkmksChanged && pBkmklist != NULL)
1045 {
1046 if (QMessageBox::warning(this, "QTReader", "Save bookmarks?", "Save", "Don't bother") == 0)
1047 savebkmks();
1048 delete pBkmklist;
1049 pBkmklist = NULL;
1050 m_fBkmksChanged = false;
1051 }
1052 bFromDocView = FALSE;
1053 saveprefs();
1054 e->accept();
1055 }
1056 else
1057 {
1058 showEditTools();
1059 }
1060}
1061
1062void QTReaderApp::do_gotomark()
1063{
1064 m_nRegAction = cGotoBkmk;
1065 listbkmk();
1066}
1067
1068void QTReaderApp::do_delmark()
1069{
1070 m_nRegAction = cDelBkmk;
1071 listbkmk();
1072}
1073
1074void QTReaderApp::listbkmk()
1075{
1076 bkmkselector->clear();
1077 int cnt = 0;
1078 if (pBkmklist != NULL)
1079 {
1080 if (m_fBkmksChanged) pBkmklist->sort();
1081 for (CList<Bkmk>::iterator i = pBkmklist->begin(); i != pBkmklist->end(); i++)
1082 {
1083#ifdef _UNICODE
1084 bkmkselector->insertItem(toQString(i->name()));
1085#else
1086 bkmkselector->insertItem(i->name());
1087#endif
1088 cnt++;
1089 }
1090 }
1091 if (cnt > 0)
1092 {
1093 menu->hide();
1094 editBar->hide();
1095 if (m_fontVisible) m_fontBar->hide();
1096 if (regVisible) regBar->hide();
1097 if (searchVisible) searchBar->hide();
1098 editorStack->raiseWidget( bkmkselector );
1099 }
1100 else
1101 QMessageBox::information(this, "QTReader", "No bookmarks in memory");
1102}
1103
1104void QTReaderApp::do_autogen()
1105{
1106 m_nRegAction = cAutoGen;
1107 regEdit->setText(m_autogenstr);
1108 do_regedit();
1109}
1110
1111void QTReaderApp::do_regedit()
1112{
1113// editBar->hide();
1114 regBar->show();
1115 regVisible = true;
1116 regEdit->setFocus();
1117}
1118
1119void QTReaderApp::gotobkmk(int ind)
1120{
1121 switch (m_nRegAction)
1122 {
1123 case cGotoBkmk:
1124 reader->locate((*pBkmklist)[ind]->value());
1125 break;
1126 case cDelBkmk:
1127 // qDebug("Deleting:%s\n",(*pBkmklist)[ind]->name());
1128 pBkmklist->erase(ind);
1129 m_fBkmksChanged = true;
1130 break;
1131 case cRmBkmkFile:
1132 unlink((const char *)Global::applicationFileName("uqtreader",bkmkselector->text(ind)));
1133 break;
1134 }
1135 showEditTools();
1136}
1137
1138void QTReaderApp::cancelbkmk()
1139{
1140 showEditTools();
1141}
1142
1143void QTReaderApp::jump()
1144{
1145 m_nRegAction = cJump;
1146 char lcn[20];
1147 sprintf(lcn, "%lu", reader->pagelocate());
1148 regEdit->setText(lcn);
1149 do_regedit();
1150}
1151
1152void QTReaderApp::do_jump(const QString& lcn)
1153{
1154 bool ok;
1155 unsigned long ulcn = lcn.toULong(&ok);
1156 if (ok)
1157 reader->locate(ulcn);
1158 else
1159 QMessageBox::information(this, "QTReader", "Must be a number");
1160}
1161
1162void QTReaderApp::do_regaction()
1163{
1164 regBar->hide();
1165 regVisible = false;
1166 switch(m_nRegAction)
1167 {
1168 case cAutoGen:
1169 do_autogen(regEdit->text());
1170 break;
1171 case cAddBkmk:
1172 do_addbkmk(regEdit->text());
1173 break;
1174 case cJump:
1175 do_jump(regEdit->text());
1176 break;
1177 case cMonoSpace:
1178 do_mono(regEdit->text());
1179 break;
1180 case cOverlap:
1181 do_overlap(regEdit->text());
1182 break;
1183 case cSetTarget:
1184 do_settarget(regEdit->text());
1185 break;
1186 }
1187 reader->restore();
1188// editBar->show();
1189 reader->setFocus();
1190}
1191
1192void QTReaderApp::do_settarget(const QString& _txt)
1193{
1194 int ind = _txt.find('/');
1195 if (ind == -1)
1196 {
1197 reader->m_targetapp = "";
1198 reader->m_targetmsg = "";
1199 QMessageBox::information(this, "QTReader", "Format is\nappname/messagename");
1200 }
1201 else
1202 {
1203 reader->m_targetapp = _txt.left(ind);
1204 reader->m_targetmsg = _txt.right(_txt.length()-ind-1);
1205 }
1206}
1207
1208void QTReaderApp::setfont()
1209{
1210 for (int i = 1; i <= m_fontSelector->count(); i++)
1211 {
1212 if (m_fontSelector->text(i) == reader->m_fontname)
1213 {
1214 m_fontSelector->setCurrentItem(i);
1215 break;
1216 }
1217 }
1218 m_fontBar->show();
1219 m_fontVisible = true;
1220}
1221
1222void QTReaderApp::do_setfont(const QString& lcn)
1223{
1224 QFont f(lcn, 10 /*, QFont::Bold*/);
1225 bkmkselector->setFont( f );
1226 regEdit->setFont( f );
1227 searchEdit->setFont( f );
1228 reader->m_fontname = lcn;
1229 reader->ChangeFont(reader->fontsizes[reader->m_textsize]);
1230 reader->refresh();
1231 m_fontBar->hide();
1232 m_fontVisible = false;
1233 showEditTools();
1234}
1235
1236void QTReaderApp::do_autogen(const QString& regText)
1237{
1238 unsigned long fs, ts;
1239 reader->sizes(fs,ts);
1240 // qDebug("Reg:%s\n", (const tchar*)(regEdit->text()));
1241 m_autogenstr = regText;
1242 QRegExp re(regText);
1243 CBuffer buff;
1244 if (pBkmklist != NULL) delete pBkmklist;
1245 pBkmklist = new CList<Bkmk>;
1246 m_fBkmksChanged = true;
1247 pbar->show();
1248pbar->resize(width(), editBar->height());
1249 pbar->reset();
1250 qApp->processEvents();
1251 reader->setFocus();
1252 reader->jumpto(0);
1253 int lastpc = 0;
1254 int i = 0;
1255 while (i >= 0)
1256 {
1257 unsigned int lcn = reader->locate();
1258 int pc = (100*lcn)/ts;
1259 if (pc != lastpc)
1260 {
1261 pbar->setProgress(pc);
1262 qApp->processEvents();
1263 if (reader->locate() != lcn) reader->jumpto(lcn);
1264 reader->setFocus();
1265 lastpc = pc;
1266 }
1267 i = reader->buffdoc.getpara(buff);
1268#ifdef _UNICODE
1269 if (re.match(toQString(buff.data())) != -1)
1270#else
1271 if (re.match(buff.data()) != -1)
1272#endif
1273 pBkmklist->push_back(Bkmk(buff.data(),lcn));
1274 }
1275 pbar->setProgress(100);
1276 qApp->processEvents();
1277 pbar->hide();
1278}
1279
1280void QTReaderApp::saveprefs()
1281{
1282// reader->saveprefs("uqtreader");
1283 Config config( "uqtreader" );
1284 config.setGroup( "View" );
1285
1286 reader->m_lastposn = reader->pagelocate();
1287
1288 config.writeEntry( "StripCr", reader->bstripcr );
1289 config.writeEntry( "StripHtml", reader->bstriphtml );
1290 config.writeEntry( "Dehyphen", reader->bdehyphen );
1291 config.writeEntry( "Unindent", reader->bunindent );
1292 config.writeEntry( "Repara", reader->brepara );
1293 config.writeEntry( "DoubleSpace", reader->bdblspce );
1294 config.writeEntry( "Indent", reader->bindenter );
1295 config.writeEntry( "FontSize", (int)(reader->fontsizes[reader->m_textsize]) );
1296 config.writeEntry( "Bold", reader->m_bBold );
1297 config.writeEntry( "ScrollDelay", reader->m_delay);
1298 config.writeEntry( "LastFile", reader->m_lastfile );
1299 config.writeEntry( "LastPosn", (int)(reader->pagelocate()) );
1300 config.writeEntry( "PageMode", reader->m_bpagemode );
1301 config.writeEntry( "MonoSpaced", reader->m_bMonoSpaced );
1302 config.writeEntry( "Fontname", reader->m_fontname );
1303 config.writeEntry( "Encoding", reader->m_encd );
1304 config.writeEntry( "CharSpacing", reader->m_charpc );
1305 config.writeEntry( "Overlap", (int)(reader->m_overlap) );
1306 config.writeEntry( "TargetApp", reader->m_targetapp );
1307 config.writeEntry( "TargetMsg", reader->m_targetmsg );
1308}
1309
1310void QTReaderApp::indentplus()
1311{
1312 reader->indentplus();
1313}
1314
1315void QTReaderApp::indentminus()
1316{
1317 reader->indentminus();
1318}
1319
1320/*
1321void QTReaderApp::oldFile()
1322{
1323 qDebug("oldFile called");
1324 reader->setText(true);
1325 qDebug("settext called");
1326 showEditTools();
1327 qDebug("showedit called");
1328}
1329*/
1330
1331/*
1332void info_cb(Fl_Widget* o, void* _data)
1333{
1334
1335 if (infowin == NULL)
1336 {
1337
1338 infowin = new Fl_Window(160,240);
1339 filename = new Fl_Output(45,5,110,14,"Filename");
1340 filesize = new Fl_Output(45,25,110,14,"Filesize");
1341 textsize = new Fl_Output(45,45,110,14,"Textsize");
1342 comprat = new CBar(45,65,110,14,"Ratio %");
1343 posn = new Fl_Output(45,85,110,14,"Location");
1344 frcn = new CBar(45,105,110,14,"% Read");
1345 about = new Fl_Multiline_Output(5,125,150,90);
1346 about->value("TWReader - $Name$\n\nA file reader program for the Agenda\n\nReads text, PalmDoc and ppms format files");
1347 Fl_Button *jump_accept = new Fl_Button(62,220,35,14,"Okay");
1348 infowin->set_modal();
1349 }
1350 if (((reader_ui *)_data)->g_filename[0] != '\0')
1351 {
1352 unsigned long fs,ts;
1353 tchar sz[20];
1354 ((reader_ui *)_data)->input->sizes(fs,ts);
1355 unsigned long pl = ((reader_ui *)_data)->input->locate();
1356
1357 filename->value(((reader_ui *)_data)->g_filename);
1358
1359 sprintf(sz,"%u",fs);
1360 filesize->value(sz);
1361
1362 sprintf(sz,"%u",ts);
1363 textsize->value(sz);
1364
1365 comprat->value(100-(100*fs + (ts >> 1))/ts);
1366
1367 sprintf(sz,"%u",pl);
1368 posn->value(sz);
1369
1370 frcn->value((100*pl + (ts >> 1))/ts);
1371 }
1372 infowin->show();
1373}
1374*/
1375
1376void QTReaderApp::savebkmks()
1377{
1378 if (pBkmklist != NULL)
1379 {
1380 BkmkFile bf((const char *)Global::applicationFileName("uqtreader",reader->m_string), true);
1381 bf.write(*pBkmklist);
1382 }
1383 m_fBkmksChanged = false;
1384}
1385
1386void QTReaderApp::readbkmks()
1387{
1388 if (pBkmklist != NULL)
1389 {
1390 delete pBkmklist;
1391 }
1392 BkmkFile bf((const char *)Global::applicationFileName("uqtreader",reader->m_string));
1393 pBkmklist = bf.readall();
1394 m_fBkmksChanged = false;
1395 if (pBkmklist == NULL)
1396 {
1397 pBkmklist = reader->getbkmklist();
1398 }
1399 if (pBkmklist != NULL)
1400 pBkmklist->sort();
1401}
1402
1403void QTReaderApp::addbkmk()
1404{
1405 m_nRegAction = cAddBkmk;
1406 regEdit->setText(reader->firstword());
1407 do_regedit();
1408}
1409
1410void QTReaderApp::do_addbkmk(const QString& text)
1411{
1412 if (text.isEmpty())
1413 {
1414 QMessageBox::information(this, "QTReader", "Need a name for the bookmark\nSelect add again", 1);
1415 }
1416 else
1417 {
1418 if (pBkmklist == NULL) pBkmklist = new CList<Bkmk>;
1419#ifdef _UNICODE
1420 CBuffer buff;
1421 int i = 0;
1422 for (i = 0; i < text.length(); i++)
1423 {
1424 buff[i] = text[i].unicode();
1425 }
1426 buff[i] = 0;
1427 pBkmklist->push_front(Bkmk(buff.data(), reader->pagelocate()));
1428#else
1429 pBkmklist->push_front(Bkmk((const tchar*)text,reader->pagelocate()));
1430#endif
1431 m_fBkmksChanged = true;
1432 }
1433}
diff --git a/noncore/apps/opie-reader/QTReaderApp.h b/noncore/apps/opie-reader/QTReaderApp.h
new file mode 100644
index 0000000..48575e9
--- a/dev/null
+++ b/noncore/apps/opie-reader/QTReaderApp.h
@@ -0,0 +1,206 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef __QTREADERAPP_H
21#define __QTREADERAPP_H
22
23//#define __ISEARCH
24
25#define MAX_ENCODING 6
26
27#include <qmainwindow.h>
28#include "QTReader.h"
29#include <qlist.h>
30#include <qpe/filemanager.h>
31#include <qmap.h>
32#include <qlineedit.h>
33#include <qstack.h>
34#include <qlistbox.h>
35#include "Queue.h"
36
37class QWidgetStack;
38class QToolButton;
39class QPopupMenu;
40class QToolBar;
41class CBkmkSelector;
42class QProgressBar;
43class QAction;
44
45#ifdef __ISEARCH
46struct searchrecord
47{
48 QString s;
49 size_t pos;
50 searchrecord(const QString& _s, size_t _pos) : s(_s), pos(_pos) {}
51};
52#endif
53
54class infowin;
55
56class QTReaderApp : public QMainWindow
57{
58 Q_OBJECT
59
60 unsigned long m_savedpos;
61
62 public:
63 QTReaderApp( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
64 ~QTReaderApp();
65
66 void openFile( const QString & );
67
68 void setScrollState(bool _b);
69
70 protected:
71 void closeEvent( QCloseEvent *e );
72 void readbkmks();
73 void do_mono(const QString&);
74 void do_jump(const QString&);
75 void do_overlap(const QString&);
76 void do_settarget(const QString&);
77 int EncNameToInt(const QString&);
78 void saveprefs();
79
80private slots:
81 void do_setfont(const QString&);
82 void encodingSelected(QAction*);
83 void msgHandler(const QCString&, const QByteArray&);
84 void monospace(bool);
85 void jump();
86 void setoverlap();
87 void settarget();
88 void setspacing();
89 void setfont();
90 void clearBkmkList();
91 void listBkmkFiles();
92 void editMark();
93 void autoScroll(bool);
94 void addbkmk();
95 void savebkmks();
96 //void importFiles();
97 void infoClose();
98 // void oldFile();
99 void showinfo();
100 void setDocument(const QString&);
101 void TBD();
102 void TBDzoom();
103
104 void indentplus();
105 void indentminus();
106
107 void fileOpen();
108
109 void editCopy();
110 void editFind();
111
112 void pageup();
113 void pagedn();
114
115 void findNext();
116 void findClose();
117
118 void regClose();
119
120#ifdef __ISEARCH
121// void search( const QString& );
122#else
123 void search();
124#endif
125
126 void openFile( const DocLnk & );
127 void showEditTools();
128
129 void stripcr(bool);
130 void striphtml(bool);
131 void dehyphen(bool);
132 void unindent(bool);
133 void repara(bool);
134 void setbold(bool);
135 void dblspce(bool);
136 void pagemode(bool);
137 // void gotobkmk(const QString& bm);
138 void gotobkmk(int);
139 void cancelbkmk();
140 void do_gotomark();
141 void do_delmark();
142 void do_autogen();
143 void do_regaction();
144
145 private:
146 void listbkmk();
147 void do_regedit();
148 void colorChanged( const QColor &c );
149 void clear();
150 void updateCaption();
151 void do_autogen(const QString&);
152 void do_addbkmk(const QString&);
153
154 private:
155
156 QAction* m_scrollButton;
157
158 QAction* m_EncodingAction[MAX_ENCODING];
159
160 CBkmkSelector* bkmkselector;
161
162 size_t searchStart;
163#ifdef __ISEARCH
164 QStack<searchrecord>* searchStack;
165 bool dosearch(size_t start, CBuffer& test, const QString& arg);
166#else
167 bool dosearch(size_t start, CBuffer& test, const QRegExp& arg);
168#endif
169 QWidgetStack *editorStack;
170 QTReader* reader;
171 QComboBox* m_fontSelector;
172 QToolBar *menu, *editBar, *searchBar, *regBar, *m_fontBar;
173 QLineEdit *searchEdit, *regEdit;
174 DocLnk *doc;
175 bool searchVisible;
176 bool regVisible;
177 bool m_fontVisible;
178 bool bFromDocView;
179 static unsigned long m_uid;
180 long unsigned get_unique_id() { return m_uid++; }
181 /*
182 void resizeEvent( QResizeEvent * r)
183 {
184 qDebug("resize:(%u,%u)", r->oldSize().width(), r->oldSize().height());
185 qDebug("resize:(%u,%u)", r->size().width(), r->size().height());
186 // bgroup->move( width()-bgroup->width(), 0 );
187 }
188 */
189 CList<Bkmk>* pBkmklist;
190 infowin* m_infoWin;
191 QProgressBar* pbar;
192 bool m_fBkmksChanged;
193 int m_nRegAction;
194 QString m_autogenstr;
195};
196
197const int cAutoGen = 0;
198const int cAddBkmk = 1;
199const int cDelBkmk = 2;
200const int cGotoBkmk = 3;
201const int cRmBkmkFile = 4;
202const int cJump = 5;
203const int cMonoSpace = 6;
204const int cOverlap = 7;
205const int cSetTarget = 8;
206#endif
diff --git a/noncore/apps/opie-reader/QtrListView.cpp b/noncore/apps/opie-reader/QtrListView.cpp
new file mode 100644
index 0000000..67040f8
--- a/dev/null
+++ b/noncore/apps/opie-reader/QtrListView.cpp
@@ -0,0 +1,24 @@
1#include "QtrListView.h"
2
3void QtrListView::keyPressEvent(QKeyEvent* e)
4{
5 switch (e->key())
6 {
7 case Key_Space:
8 e->accept();
9 emit OnCentreButton(currentItem());
10 break;
11 //case Key_Enter:
12 //case Key_Return:
13 case Key_F33:
14 e->accept();
15 emit OnOKButton(currentItem());
16 break;
17 case Key_Escape:
18 e->accept();
19 emit OnCancelButton();
20 break;
21 default:
22 QListView::keyPressEvent(e);
23 }
24}
diff --git a/noncore/apps/opie-reader/QtrListView.h b/noncore/apps/opie-reader/QtrListView.h
new file mode 100644
index 0000000..c1b7f4d
--- a/dev/null
+++ b/noncore/apps/opie-reader/QtrListView.h
@@ -0,0 +1,20 @@
1#ifndef __QTRLISTVIEW_H
2#define __QTRLISTVIEW_H
3
4#include <qlistview.h>
5
6class QtrListView : public QListView
7{
8 Q_OBJECT
9
10 virtual void keyPressEvent(QKeyEvent* e);
11 public:
12 QtrListView(QWidget* parent, char* name) : QListView(parent, name) {};
13
14 signals:
15 void OnOKButton(QListViewItem*);
16 void OnCentreButton(QListViewItem*);
17 void OnCancelButton();
18};
19
20#endif
diff --git a/noncore/apps/opie-reader/Queue.h b/noncore/apps/opie-reader/Queue.h
new file mode 100644
index 0000000..f1bd4b4
--- a/dev/null
+++ b/noncore/apps/opie-reader/Queue.h
@@ -0,0 +1,21 @@
1#ifndef __QUEUE_H
2#define __QUEUE_H
3
4#include "my_list.h"
5
6template<class T>
7class CQueue : public CList<T>
8{
9 public:
10 bool empty() { return (front == NULL); }
11 void push(const T& t) { push_back(t); }
12 T pop()
13 {
14 T data = front->data;
15 node* n = front;
16 front = front->next;
17 delete n;
18 return data;
19 }
20};
21#endif
diff --git a/noncore/apps/opie-reader/README b/noncore/apps/opie-reader/README
new file mode 100644
index 0000000..d091010
--- a/dev/null
+++ b/noncore/apps/opie-reader/README
@@ -0,0 +1,162 @@
1What is QT Reader?
2==================
3
4QT Reader is an e-text reading program which understands several
5varieties of PalmDoc format (types 1,2 and 4), zTxt, plain text and
6gzipped text.
7
8In addition it supports its own very highly compressed format which is
9based on ppm (regarded by many as the best available compression
10technique) with modifications by Fabrice Bellard for speed and memory
11efficiency and by myself to support random access on smaller
12devices. I call this modified format ppms (for ppm, segmented).
13
14The ppms program which is used to produce ppms files from plain text
15is available from http://www.timwentford.uklinux.net where there is
16also a comparison of file sizes produced by several compression
17methods. This is summarised below:
18
19Compression method Size in bytes Memory required to decompress
20Plain text 573714 N/A
21Makedoc (PalmDoc format) 329543 2k
22ppms (default) 184187 350k
23ppms (best) 151733 800k
24bzip2 -1 180175 340k
25bzip2 -9 154280 2.2M
26
27The default settings used here were chosen to suit the Agenda VR3. I
28would expect the Zaurus to be able to use settings which give 170kb
29file size and 500k memory without any problem. The format encodes the
30settings used so the user may choose whatever suits them. I choose
31based on the amount of memory required and on whether or not pageup
32performance is acceptable.
33
34General Use
35===========
36
37Start it up and then choose "File/Open" from the menu. Select a
38palmdoc, plain text, gzipped text or ppms file from the file selector
39and use the cursor keys to page up/down (up/down keys) and to make the
40text size comfortable (left/right keys) and thats it for most
41uses. See below for more advanced use.
42
43What the Menu Options Do
44========================
45
46File
47====
48
49File operations live in this menu.
50
51Open Brings up the file selector to allow you to choose a
52 new file to read.
53Info Displays info about the currently open file. Needs
54 reformatting.
55Start Block Marks the text at the top of the currently displayed
56 page ready for copying.
57Copy Block Copies all text from the mark to the bottom of the
58 currently displayed page to the clipboard.
59Scroll Starts/stops autoscroll. The speed can be adjusted
60 using the up/down keys while autoscroll is on (page
61 up and down are still functional and can be activated
62 by using the up and down arrows on the task bar).
63Jump Jumps to a specific offset in the file. If you note
64 down the current location from the File/Info display
65 you can then jump to the same position again using
66 this function (or you could bokmark it 8^)).
67Page/Line scroll When this is On pressing the arrows (keys or
68 icons on the task bar) moves you a page at a time.
69 When this is off, pressing the arrows moves you a
70 line at a time.
71Set Overlap Sets the number of lines of overlap between pages
72 when scrolling by page.
73Set Dictionary When you tap on the screen the word under the
74 pointer is copied to the clipboard ready for pasting
75 into (e.g.) a dictionary program. Using this function
76 allows the word to be sent to compatible dictionary
77 programs direct. The format is exename/messagename
78 where exename is the name of the executable for the
79 dictionary program and messagename is the name of the
80 message it is expecting. You can get some idea of how
81 it works by using some debug functionality which I
82 deliberately left in QTReader. Set this to
83 uqtreader/info.
84 To deactivate it again, set it to /.
85Find Brings up the search requester where you can enter a
86 regular expression to search (again) for.
87
88Format
89======
90
91Used to alter the way the text is reformatted before display.
92
93Strip CR Removes those pesky DOS crs from the file.
94Strip HTML Uses a very simple minded filter to remove html mark-up.
95Dehyphen Removes hyphens from e-texts which have been formatted to
96 fit on different sized displays by hyphenating words
97 which no longer appear at the end of the line.
98Unindent Removes leading spaces from the beginning of paragraphs.
99Re-paragraph Removes/adds line breaks as necessary to make the text
100 look nice on the display.
101Double Space Adds an extra space between paragraphs.
102Indent+ Increases the number of extra leading spaces inserted
103 before paragraphs.
104Indent- Decreases the number of extra leading spaces inserted
105 before paragraphs.
106 Bold Sets the font to bold (if its supported by the currently
107 selected font).
108
109For e-texts from fictionwise I don't need any of these enabled. For
110Project Gutenberg e-texts I enable Strip CR, Re-paragraph and either 3 lots
111of indent+ and/or double space.
112
113Zoom Menu option not implemented but pops up an info box
114 telling you that left/right cursor keys will zoom
115 out/in.
116Ideogram/Char grouping When selected, treats each character as a word
117 and enforces uniform character spacing - suitable for
118 many eastern character sets. When not selected, looks for
119 spaces in the text to identify words - suitable for most
120 western texts. (I'm not a language expert so forgive my,
121 probably inaccurate, generalisations).
122Set Width Sets the character spacing as a percentage of the text
123 height to be used when in ideogram mode. Start at 100 and
124 experiment to find what you like best.
125Encoding Allows you to choose from a variety of codings. Ascii is
126 actually unprocessed text so its precise behaviour may
127 depend on the machines locale setting. Palm and code page
128 1252 are very similar and are useful if you have an etext
129 aimed at Palms or Windows machines which use an extended
130 character set - though you will need to use a unicode
131 enabled font to show all the characters. The U... fonts
132 are different varieties of unicode encodings. If you
133 don't know what that means you probably don't need them
134 (they allow texts to access the full range of characters
135 required for non US English languages).
136Set Font Allows you to choose which font the text is displayed
137 in. Helvetica or smoothtimes are probably best for ascii type
138 texts, unifont or cyberbit (if you have installed them)
139 are best for extended character sets (other unicode fonts
140 may also be available but these are all I've found, so far).
141Marks
142=====
143
144 Mark Saves the current position as a bookmark
145Goto Allows selection of a bookmark to jump to.
146Delete Deletes an unwanted bookmark from the current text.
147Autogen Displays a box for entering a regular
148 expression which will be used to determine which
149 paragraphs (not lines) will be marked to allow jumping to
150 directly using the Goto option. The format options
151 described above are applied before the regular expression
152 matching is done.
153 This operation is performed in the background allowing
154 you to continue paging up/down the e-text.
155Clear Deletes all in-memory bookmarks from the current document.
156Save Saves the "in-memory" bookmarks to disk.
157Tidy Deletes bookmark file for a document. The operations
158 above work on an in-memory copy of the bookmarks. This
159 option makes that copy more permanent (you will also be
160 prompted to save the bookmarks when closing a text if the
161 in-memory copy is different to the saved copy).
162
diff --git a/noncore/apps/opie-reader/Text.h b/noncore/apps/opie-reader/Text.h
new file mode 100644
index 0000000..4c689be
--- a/dev/null
+++ b/noncore/apps/opie-reader/Text.h
@@ -0,0 +1,28 @@
1#ifndef __Text_h
2#define __Text_h
3#include <stdio.h>
4#include <sys/stat.h>
5#include "CExpander.h"
6
7class Text: public CExpander {
8 FILE* file;
9public:
10 Text() : file(NULL) {};
11 virtual ~Text() { if (file != NULL) fclose(file); }
12 virtual int openfile(const tchar *src)
13 {
14 if (file != NULL) fclose(file);
15 return ((file = fopen(src,"rb")) == NULL);
16 }
17 virtual int getch() { return fgetc(file); }
18 virtual unsigned int locate() { return ftell(file); }
19 virtual void locate(unsigned int n) { fseek(file,n,SEEK_SET); }
20 virtual bool hasrandomaccess() { return true; }
21 virtual void sizes(unsigned long& _file, unsigned long& _text)
22 {
23 struct stat _stat;
24 fstat(fileno(file),&_stat);
25 _text = _file = _stat.st_size;
26 }
27};
28#endif
diff --git a/noncore/apps/opie-reader/ZText.h b/noncore/apps/opie-reader/ZText.h
new file mode 100644
index 0000000..2848af7
--- a/dev/null
+++ b/noncore/apps/opie-reader/ZText.h
@@ -0,0 +1,35 @@
1#ifndef __Text_h
2#define __Text_h
3#include <stdio.h>
4#include <zlib.h>
5#include <sys/stat.h>
6
7#include "CExpander.h"
8
9class Text: public CExpander {
10 gzFile file;
11 unsigned long fsize;
12public:
13 Text() : file(NULL) {};
14 virtual ~Text()
15 {
16 if (file != NULL) gzclose(file);
17 }
18 virtual int openfile(const char *src)
19 {
20 if (file != NULL) gzclose(file);
21 struct stat _stat;
22 stat(src,&_stat);
23 fsize = _stat.st_size;
24 return ((file = gzopen(src,"rb")) == NULL);
25 }
26 virtual int getch() { return gzgetc(file); }
27 virtual unsigned int locate() { return gztell(file); }
28 virtual void locate(unsigned int n) { gzseek(file,n,SEEK_SET); }
29 virtual bool hasrandomaccess() { return true; }
30 virtual void sizes(unsigned long& _file, unsigned long& _text)
31 {
32 _text = _file = fsize;
33 }
34};
35#endif
diff --git a/noncore/apps/opie-reader/arith.h b/noncore/apps/opie-reader/arith.h
new file mode 100644
index 0000000..19ca646
--- a/dev/null
+++ b/noncore/apps/opie-reader/arith.h
@@ -0,0 +1,43 @@
1/*
2 * Encodage & décodage arithmétique
3 */
4
5#ifndef ARITH_H
6
7#define ARITH_H
8
9#include "utypes.h"
10#include <stdio.h>
11
12class PPM_ReadBuf
13{
14 FILE *my_file_in;
15public:
16 PPM_ReadBuf(FILE* f) : my_file_in(f) {}
17 UINT readbuf(UCHAR *buf,UINT len)
18 {
19 UINT len1;
20 len1=fread(buf,1,len,my_file_in);
21 return len1;
22 }
23};
24
25class ArithClass
26{
27
28UCHAR *ainbuf;
29UCHAR *apinbuf,*aendinbuf;
30UINT ainbufsize;
31USHORT avalue,alow,ahigh;
32PPM_ReadBuf* areadbuf;
33UCHAR abitcnt;
34USHORT abitbuf;
35
36 public:
37void Arith_DecodeInit(PPM_ReadBuf* readbuf,UCHAR *buf,UINT bufsize);
38UINT Arith_DecodeVal(UINT size);
39void Arith_Decode(UINT min,UINT max,UINT size);
40void Arith_DecodeEnd(void);
41
42};
43#endif
diff --git a/noncore/apps/opie-reader/arith_d.cpp b/noncore/apps/opie-reader/arith_d.cpp
new file mode 100644
index 0000000..c43d697
--- a/dev/null
+++ b/noncore/apps/opie-reader/arith_d.cpp
@@ -0,0 +1,94 @@
1/* décodage arithmétique
2 * optimisé pour une arithmétique 16 bits
3 */
4#include <stdlib.h>
5#include "arith.h"
6
7
8/*
9 * Initialisation du décodeur.
10 * bufsize doit être multiple de 2 et supérieur à 4
11 */
12
13void ArithClass::Arith_DecodeInit(PPM_ReadBuf* readbuf,UCHAR *buf,UINT bufsize) {
14
15 /* gestion buffer */
16
17 ainbuf=buf;
18 ainbufsize=bufsize;
19 areadbuf=readbuf;
20 aendinbuf=ainbuf+ainbufsize;
21 areadbuf->readbuf(ainbuf,ainbufsize);
22 apinbuf=ainbuf;
23
24 /* intervalle et position dans l'intervalle */
25 alow=0;
26 ahigh=0xFFFF;
27 avalue=(*apinbuf++)<<8;
28 avalue|=(*apinbuf++);
29
30 /* remplissage du buffer 16 bits */
31
32 abitbuf=(*apinbuf++)<<8;
33 abitbuf|=(*apinbuf++);
34 abitcnt=16;
35}
36
37 #define DIV16(a,b) ( (UINT)(a)/(UINT)(b) )
38 #define MUL16(a,b) ( (UINT)(a)*(UINT)(b) )
39
40/*
41 * Décodage: première étape
42 */
43
44UINT ArithClass::Arith_DecodeVal(UINT asize) {
45 USHORT range,c;
46
47 range=ahigh-alow+1;
48 c=avalue-alow+1;
49 if (range!=0) {
50 if (c==0) return DIV16(((UINT)asize<<16)-1,range);
51 else return DIV16(MUL16(c,asize)-1,range);
52 } else {
53 if (c==0) return (asize-1);
54 else return (MUL16(c,asize)-1)>>16;
55 }
56}
57
58/*
59 * Décodage: deuxième étape
60 */
61
62void ArithClass::Arith_Decode(UINT amin,UINT amax,UINT asize) {
63 USHORT range;
64
65 range = ahigh - alow;
66 if (amax!=asize) ahigh=alow+DIV16(MUL16(range,amax)+amax,asize)-1;
67 if (amin!=0) alow+=DIV16(MUL16(range,amin)+amin,asize);
68 for ( ; ; ) {
69 if ( alow>=0x4000 && ahigh<0xC000 ) {
70 avalue -= 0x4000; alow -= 0x4000; ahigh -= 0x4000;
71 } else if ( ahigh>=0x8000 && alow<0x8000 ) break;
72
73 alow+=alow;
74 ahigh+=ahigh+1;
75 avalue=(avalue<<1)|( (abitbuf&0x8000)!=0 );
76 abitbuf<<=1;
77 if ( (--abitcnt)==0 ) {
78 abitbuf=(*apinbuf++)<<8;
79 abitbuf|=(*apinbuf++);
80 abitcnt=16;
81 if (apinbuf>=aendinbuf) {
82 areadbuf->readbuf(ainbuf,ainbufsize);
83 apinbuf=ainbuf;
84 }
85 }
86 }
87}
88
89/*
90 * fin du décodage: rien à faire
91 */
92
93void ArithClass::Arith_DecodeEnd(void) {
94}
diff --git a/noncore/apps/opie-reader/cbkmkselector.h b/noncore/apps/opie-reader/cbkmkselector.h
new file mode 100644
index 0000000..1a49c5a
--- a/dev/null
+++ b/noncore/apps/opie-reader/cbkmkselector.h
@@ -0,0 +1,41 @@
1#include <qwidget.h>
2#include <qlistbox.h>
3#include <qpushbutton.h>
4#include <qlayout.h>
5
6class CBkmkSelector : public QWidget
7{
8
9 Q_OBJECT
10
11 QListBox* bkmkselector;
12
13signals:
14 void selected(int i);
15 void cancelled();
16private slots:
17 void slotSelected(QListBoxItem* t) { emit selected(bkmkselector->index(t)); }
18 void slotSelected(int t) { emit selected(t); }
19 void slotCancel() { emit cancelled(); }
20public:
21 CBkmkSelector( QWidget *parent=0, const char *name=0, WFlags f = 0) :
22 QWidget(parent, name, f)
23 {
24
25// QFont f("unifont", 16);
26// setFont( f );
27
28 QVBoxLayout* grid = new QVBoxLayout(this);
29 bkmkselector = new QListBox(this, "Bookmarks");
30 QPushButton* exitButton = new QPushButton("Cancel", this);
31 connect(bkmkselector, SIGNAL( selected(int) ), this, SLOT( slotSelected(int) ) );
32 connect(bkmkselector, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( slotSelected(QListBoxItem*) ) );
33 connect(exitButton, SIGNAL( released() ), this, SLOT( slotCancel() ) );
34 grid->addWidget(bkmkselector,1);
35 grid->addWidget(exitButton);
36 }
37 void clear() { bkmkselector->clear(); }
38 void insertItem(const QString& item) { bkmkselector->insertItem(item); }
39 QString text(int index) const { return bkmkselector->text(index); }
40};
41
diff --git a/noncore/apps/opie-reader/config.h b/noncore/apps/opie-reader/config.h
new file mode 100644
index 0000000..5150270
--- a/dev/null
+++ b/noncore/apps/opie-reader/config.h
@@ -0,0 +1,21 @@
1#ifndef __CONFIG_H
2#define __CONFIG_H
3
4#define _UNICODE
5
6#ifdef _UNICODE
7#include <limits.h>
8
9#define UTF8
10
11typedef unsigned short tchar;
12const tchar UEOF = USHRT_MAX;
13
14#else
15typedef char tchar;
16const int UEOF = -1;
17#endif
18
19#include "ustring.h"
20
21#endif
diff --git a/noncore/apps/opie-reader/fileBrowser.cpp b/noncore/apps/opie-reader/fileBrowser.cpp
new file mode 100644
index 0000000..def988f
--- a/dev/null
+++ b/noncore/apps/opie-reader/fileBrowser.cpp
@@ -0,0 +1,185 @@
1/****************************************************************************
2
3Derived from a file browser which was
4
5** copyright 2001 ljp ljp@llornkcor.com
6
7Extensive modification by Tim Wentford to allow it to work in rotated mode
8
9****************************************************************************/
10#include "fileBrowser.h"
11
12#include "QtrListView.h"
13#include <qpushbutton.h>
14#include <qfile.h>
15#include <qmessagebox.h>
16#include <unistd.h>
17#include <qlayout.h>
18
19fileBrowser::fileBrowser( QWidget* parent, const char* name, bool modal, WFlags fl , const QString filter, const QString iPath )
20 : QDialog( parent, name, modal, fl )
21{
22// showMaximized();
23 if ( !name )
24 setName( "fileBrowser" );
25 if (parent != NULL) resize( parent->width(), parent->height() );
26 setCaption(tr( "Browse for file" ) );
27 filterStr=filter;
28
29 buttonOk = new QPushButton( this, "buttonOk" );
30 buttonOk->setFixedSize( 25, 25 );
31 buttonOk->setText( tr( "/" ) );
32
33 dirLabel = new QLabel(this, "DirLabel");
34 dirLabel->setText(currentDir.canonicalPath());
35
36 ListView = new QtrListView( this, "ListView" );
37 ListView->addColumn( tr( "Name" ) );
38 ListView->setSorting( 2, FALSE);
39 ListView->addColumn( tr( "Size" ) );
40 ListView->setSelectionMode(QListView::Single);
41
42 ListView->setAllColumnsShowFocus( TRUE );
43
44 // signals and slots connections
45 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( OnRoot() ) );
46 connect( ListView, SIGNAL(doubleClicked( QListViewItem*)), SLOT(listDoubleClicked(QListViewItem *)) );
47 connect( ListView, SIGNAL(clicked( QListViewItem*)), SLOT(listClicked(QListViewItem *)) );
48 connect( ListView, SIGNAL(OnOKButton( QListViewItem*)), SLOT(listClicked(QListViewItem *)) );
49 connect( ListView, SIGNAL(OnCentreButton( QListViewItem*)), SLOT(listClicked(QListViewItem *)) );
50 connect( ListView, SIGNAL(OnCancelButton()), SLOT(OnCancel()) );
51
52 QVBoxLayout* grid = new QVBoxLayout(this);
53 QHBoxLayout* hgrid = new QHBoxLayout(grid);
54 hgrid->addWidget(dirLabel,1);
55 hgrid->addWidget(buttonOk);
56 grid->addWidget(ListView,1);
57
58 if (QFileInfo(iPath).exists())
59 {
60 currentDir.setPath(iPath);
61 chdir(iPath.latin1());
62 }
63 else
64 {
65 currentDir.setPath(QDir::currentDirPath());
66 chdir(QDir::currentDirPath().latin1());
67 }
68
69 populateList();
70}
71
72void fileBrowser::resizeEvent(QResizeEvent* e)
73{
74 ListView->setColumnWidth(1,(ListView->width())/4);
75 ListView->setColumnWidth(0,ListView->width()-20-ListView->columnWidth(1));
76}
77
78fileBrowser::~fileBrowser()
79{
80}
81
82
83void fileBrowser::populateList()
84{
85 ListView->clear();
86//qDebug(currentDir.canonicalPath());
87// currentDir.setFilter( QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks );
88 currentDir.setFilter( QDir::All );
89 currentDir.setSorting(/* QDir::Size*/ /*| QDir::Reversed | */QDir::DirsFirst);
90 currentDir.setMatchAllDirs(TRUE);
91
92 currentDir.setNameFilter(filterStr);
93// currentDir.setNameFilter("*.txt;*.etx");
94 QString fileL, fileS;
95 const QFileInfoList *list = currentDir.entryInfoList(QDir::All);
96 QFileInfoListIterator it(*list);
97 QFileInfo *fi;
98 while ( (fi=it.current()) )
99 {
100 if (fi->fileName() != ".")
101 {
102 fileS.sprintf( "%10li", fi->size() );
103 fileL.sprintf( "%s",fi->fileName().data() );
104 if( fi->isDir() )
105 {
106 fileL+="/";
107 }
108 else
109 {
110// qDebug("Not a dir: "+currentDir.canonicalPath()+fileL);
111 }
112 new QListViewItem( ListView,fileL,fileS );
113 }
114 ++it;
115 }
116 ListView->setSorting( 2, FALSE);
117 dirLabel->setText("Current Directory:\n"+currentDir.canonicalPath());
118}
119
120void fileBrowser::upDir()
121{
122// qDebug(currentDir.canonicalPath());
123}
124
125void fileBrowser::listClicked(QListViewItem *selectedItem)
126{
127 if (selectedItem == NULL) return;
128 QString strItem=selectedItem->text(0);
129
130// qDebug("%s", (const char*)strItem);
131
132
133 QString strSize=selectedItem->text(1);
134
135 strSize.stripWhiteSpace();
136
137 bool ok;
138
139 QFileInfo fi(strItem);
140 while (fi.isSymLink()) fi.setFile(fi.readLink());
141 if (fi.isDir())
142 {
143 strItem=QDir::cleanDirPath(currentDir.canonicalPath()+"/"+strItem);
144
145 if(QDir(strItem).exists())
146 {
147 currentDir.cd(strItem, TRUE);
148 populateList();
149 }
150 } else
151 OnOK();
152 chdir(strItem.latin1());
153//
154
155}
156
157// you may want to switch these 2 functions. I like single clicks
158void fileBrowser::listDoubleClicked(QListViewItem *selectedItem)
159{
160}
161
162void fileBrowser::OnOK() {
163
164 QListViewItemIterator it1( ListView);
165 for ( ; it1.current(); ++it1 ) {
166 if ( it1.current()->isSelected() ) {
167 selectedFileName=QDir::cleanDirPath(currentDir.canonicalPath()+"/"+it1.current()->text(0));
168 // qDebug("selected filename is "+selectedFileName);
169 fileList.append( selectedFileName );
170 }
171 }
172 accept();
173}
174
175void fileBrowser::OnRoot()
176{
177 currentDir.cd("/", TRUE);
178 populateList();
179 chdir("/");
180}
181
182void fileBrowser::OnCancel()
183{
184 reject();
185}
diff --git a/noncore/apps/opie-reader/fileBrowser.h b/noncore/apps/opie-reader/fileBrowser.h
new file mode 100644
index 0000000..d222791
--- a/dev/null
+++ b/noncore/apps/opie-reader/fileBrowser.h
@@ -0,0 +1,70 @@
1/*
2Derived from the file browser published by ljp@llornkcor.com but extensively
3modified to work in rotated views on the Zaurus
4*/
5
6/****************************************************************************
7** Form interface generated from reading ui file 'fileBrowzer.ui'
8**
9** Created: Fri Dec 14 08:16:02 2001
10** by: The User Interface Compiler (uic)
11**
12** WARNING! All changes made in this file will be lost!
13blah,blah,blah
14****************************************************************************/
15#ifndef FILEBROWSER_H
16#define FILEBROWSER_H
17
18//#include <qvariant.h>
19#include <qdialog.h>
20#include <qfile.h>
21#include <qdir.h>
22#include <qstringlist.h>
23#include <qlabel.h>
24#include <qstring.h>
25
26class QVBoxLayout;
27class QHBoxLayout;
28class QGridLayout;
29class QtrListView;
30class QListViewItem;
31class QPushButton;
32
33class fileBrowser : public QDialog
34{
35 Q_OBJECT
36
37public:
38 void populateList();
39 fileBrowser( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ,const QString filter=0, const QString iPath=0);
40 ~fileBrowser();
41
42 QPushButton* buttonOk;
43 QtrListView* ListView;
44 QPushButton* buttonCancel;
45 QLabel *dirLabel;
46 QString selectedFileName, filterStr;
47 QDir currentDir;
48 QFile file;
49 QStringList fileList;
50
51//QListViewItem * item;
52public slots:
53
54private:
55
56private slots:
57 void upDir();
58 void listDoubleClicked(QListViewItem *);
59 void listClicked(QListViewItem *);
60 void OnRoot();
61 void OnCancel();
62
63protected slots:
64
65protected:
66 void OnOK();
67 virtual void resizeEvent(QResizeEvent* e);
68};
69
70#endif // FILEBROWSER_H
diff --git a/noncore/apps/opie-reader/infowin.cpp b/noncore/apps/opie-reader/infowin.cpp
new file mode 100644
index 0000000..f9a6f5f
--- a/dev/null
+++ b/noncore/apps/opie-reader/infowin.cpp
@@ -0,0 +1,41 @@
1#include "infowin.h"
2#include "version.h"
3
4#define VERSION_STRING "QT Reader v" ## MAJOR ## "." ## MINOR ## " (" ## RELEASE_TYPE ## ")\nA small e-text reader"
5
6infowin::infowin( QWidget *parent=0, const char *name=0, WFlags f = 0) :
7 QWidget(parent, name, f)
8{
9 grid = new QGridLayout(this, 6, 2);
10 QLabel* l;
11 l = new QLabel("Compressed file size", this);
12 grid->addWidget(l, 0, 0);
13 fileSize = new QLabel("0", this);
14 fileSize->setAlignment( AlignVCenter | AlignRight );
15 grid->addWidget(fileSize, 0, 1);
16 l = new QLabel("Original text size", this);
17 grid->addWidget(l, 1, 0);
18 textSize = new QLabel("0", this);
19 textSize->setAlignment( AlignVCenter | AlignRight );
20 grid->addWidget(textSize, 1, 1);
21 l = new QLabel("Compression Ratio", this);
22 grid->addWidget(l, 2, 0);
23 ratio = new QLabel("0", this);
24 grid->addWidget(ratio, 2, 1);
25 ratio->setAlignment( AlignVCenter | AlignRight );
26 l = new QLabel("Current location", this);
27 grid->addWidget(l, 3, 0);
28 location = new QLabel("0", this);
29 location->setAlignment( AlignVCenter | AlignRight );
30 grid->addWidget(location, 3, 1);
31 l = new QLabel("Per centage read", this);
32 grid->addWidget(l, 4, 0);
33 read = new QLabel("0", this);
34 read->setAlignment( AlignVCenter | AlignRight );
35 grid->addWidget(read, 4, 1);
36 l = new QLabel(VERSION_STRING, this);
37 grid->addWidget(l, 5, 0);
38 QPushButton* exitbutton = new QPushButton("Cancel", this);
39 connect( exitbutton, SIGNAL( released() ), this, SLOT( infoClose() ) );
40 grid->addWidget(exitbutton, 5, 1);
41}
diff --git a/noncore/apps/opie-reader/infowin.h b/noncore/apps/opie-reader/infowin.h
new file mode 100644
index 0000000..9ddce36
--- a/dev/null
+++ b/noncore/apps/opie-reader/infowin.h
@@ -0,0 +1,52 @@
1#ifndef __INFOWIN_H
2#define __INFOWIN_H
3
4#include <qlayout.h>
5#include <qpushbutton.h>
6#include <qgrid.h>
7#include <qlabel.h>
8
9class infowin : public QWidget
10{
11Q_OBJECT
12 QLabel* fileSize;
13 QLabel* textSize;
14 QLabel* ratio;
15 QLabel* location;
16 QLabel* read;
17 QGridLayout* grid;
18public:
19 infowin::infowin( QWidget *parent=0, const char *name=0, WFlags f = 0);
20/*
21 void addcancel(QPushButton* exitbutton)
22 {
23 grid->addWidget(exitbutton, 5, 1);
24 }
25*/
26 void setFileSize(int sz) { fileSize->setNum(sz); }
27 void setTextSize(int sz) { textSize->setNum(sz); }
28 void setRatio(int sz) { ratio->setText(QString().setNum(sz)+"%"); }
29 void setLocation(int sz) { location->setNum(sz); }
30 void setRead(int sz) { read->setText(QString().setNum(sz)+"%"); }
31/*
32 virtual void keyPressEvent(QKeyEvent* e)
33 {
34 printf("Received:%d\n", e->key());
35 switch (e->key())
36 {
37 case Key_Escape:
38 e->accept();
39 emit Close();
40 break;
41 default:
42 e->ignore();
43 }
44 }
45*/
46private slots:
47 void infoClose() { emit Close(); }
48 signals:
49 void Close();
50};
51
52#endif
diff --git a/noncore/apps/opie-reader/main.cpp b/noncore/apps/opie-reader/main.cpp
new file mode 100644
index 0000000..e37f12c
--- a/dev/null
+++ b/noncore/apps/opie-reader/main.cpp
@@ -0,0 +1,38 @@
1#include <qpe/qpeapplication.h>
2//#include <qmainwindow.h>
3#include "QTReaderApp.h"
4
5
6
7
8
9/*
10class myapp : public QPEApplication
11{
12 public slots:
13 void receive( const QCString& msg, const QByteArray& data )
14 {
15
16 QDataStream stream( data, IO_ReadOnly );
17 if ( msg == "someMessage(int,int,int)" ) {
18 int a,b,c;
19 stream >> a >> b >> c;
20 ...
21 } else if ( msg == "otherMessage(QString)" ) {
22 ...
23 }
24
25 }
26}
27*/
28
29int main( int argc, char ** argv )
30{
31 QPEApplication a( argc, argv );
32
33 QTReaderApp m;
34 a.showMainDocumentWidget( &m );
35
36 return a.exec();
37}
38
diff --git a/noncore/apps/opie-reader/my_list.h b/noncore/apps/opie-reader/my_list.h
new file mode 100644
index 0000000..b3f0cc0
--- a/dev/null
+++ b/noncore/apps/opie-reader/my_list.h
@@ -0,0 +1,172 @@
1#ifndef __MY_LIST_H
2#define __MY_LIST_H
3
4template<class T>
5class CList
6{
7 struct node
8 {
9 T data;
10 node* next;
11 node(T _data, node* _next = NULL) : data(_data), next(_next) {}
12 node() : next(NULL) {};
13 };
14 protected:
15 node* front;
16 node* back;
17 public:
18 CList() : front(NULL), back(NULL) {}
19 ~CList()
20 {
21 if (front != NULL)
22 {
23 while (front != NULL)
24 {
25 node *p = front;
26 front = p->next;
27 delete p;
28 }
29 }
30 }
31 T* operator[](int n)
32 {
33 node* current = front;
34 while (n-- > 0)
35 {
36 if ((current = current->next) == NULL)
37 return NULL;
38 }
39 return &(current->data);
40 }
41 void push_front(const T& t)
42 {
43 node* n = new node(t,front);
44 if (front == NULL)
45 {
46 front = back = n;
47 }
48 else
49 front = n;
50 }
51 void push_back(const T& t)
52 {
53 node* n = new node(t);
54 if (front == NULL)
55 {
56 front = back = n;
57 }
58 else
59 {
60 back->next = n;
61 back = n;
62 }
63 }
64 void erase(unsigned int n)
65 {
66 node* p = front;
67 node* last = front;
68 while (n-- > 0)
69 {
70 last = p;
71 p = p->next;
72 if (p == NULL) return;
73 }
74 if (p == front)
75 {
76 front = p->next;
77 }
78 else
79 {
80 last->next = p->next;
81 }
82 if (p == back)
83 {
84 back = last;
85 }
86 delete p;
87 }
88 void sort()
89 {
90 int i,j,inc,n;
91 T v;
92 T* item;
93 node* t;
94 t = front;
95 n = 0;
96 while (t != NULL)
97 {
98 n++;
99 t = t->next;
100 }
101 if (n >= 2)
102 {
103 item = new T[n];
104 i = 0;
105 t = front;
106 for (t = front, i = 0; t != NULL; t = t->next, i++)
107 {
108 item[i] = t->data;
109 }
110
111 for (inc = 1; inc <= n; inc = 3*inc+1);
112
113 do
114 {
115 inc /= 3;
116 for (i = inc; i < n; i++)
117 {
118 v = item[i];
119 for (j = i; v < item[j-inc] && j >= inc; j -= inc)
120 {
121 item[j] = item[j-inc];
122 }
123 item[j] = v;
124 }
125 }
126 while (inc > 1);
127 for (t = front, i = 0; t != NULL; t = t->next, i++)
128 {
129 t->data = item[i];
130 }
131 // back = *(item[n-1]);
132 delete [] item;
133 }
134 }
135 class iterator
136 {
137 node* current;
138 public:
139 iterator(node* _c) : current(_c) {}
140 iterator& operator++()
141 {
142 current = current->next;
143 return *this;
144 }
145 iterator& operator++(int)
146 {
147 current = current->next;
148 return *this;
149 }
150 T operator*()
151 {
152 return current->data;
153 }
154 T* operator->()
155 {
156 return &(current->data);
157 }
158 bool operator!=(iterator t)
159 {
160 return (current != t.current);
161 }
162 };
163 iterator begin()
164 {
165 return iterator(front);
166 }
167 iterator end()
168 {
169 return iterator(NULL);
170 }
171};
172#endif
diff --git a/noncore/apps/opie-reader/opie-reader.control b/noncore/apps/opie-reader/opie-reader.control
new file mode 100644
index 0000000..e8c98bb
--- a/dev/null
+++ b/noncore/apps/opie-reader/opie-reader.control
@@ -0,0 +1,9 @@
1Files: bin/uqtreader apps/Applications/uqtreader.desktop pics/uqtreader.png pics/panel-arrow-down.png
2Priority: optional
3Section: applications
4Maintainer: Tim Wentford <timwentford@hotmail.com>
5Architecture: arm
6Version: 0_3r_beta_UTF8
7Depends:
8License: GPL
9Description: E-Book reader
diff --git a/noncore/apps/opie-reader/opie-reader.pro b/noncore/apps/opie-reader/opie-reader.pro
new file mode 100644
index 0000000..c4a87a4
--- a/dev/null
+++ b/noncore/apps/opie-reader/opie-reader.pro
@@ -0,0 +1,48 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 HEADERS = Aportis.h \
4 BuffDoc.h \
5 CBuffer.h \
6 CExpander.h \
7 CFilter.h \
8 QTReader.h \
9 QTReaderApp.h \
10 Text.h \
11 ZText.h \
12 arith.h \
13 my_list.h \
14 ppm.h \
15 ppm_expander.h \
16 cbkmkselector.h \
17 fileBrowser.h \
18 ztxt.h \
19 QtrListView.h \
20 infowin.h \
21 version.h \
22 pdb.h \
23 utypes.h \
24 ustring.h \
25 CEncoding.h \
26 config.h
27 SOURCES = Aportis.cpp \
28 BuffDoc.cpp \
29 CBuffer.cpp \
30 QTReader.cpp \
31 QTReaderApp.cpp \
32 arith_d.cpp \
33 main.cpp \
34 ppm.cpp \
35 ppm_expander.cpp \
36 ztxt.cpp \
37 QtrListView.cpp \
38 infowin.cpp \
39 pdb.cpp \
40 CEncoding.cpp \
41 fileBrowser.cpp
42 INTERFACES=
43 DESTDIR = $(OPIEDIR)/bin
44 INCLUDEPATH+= $(OPIEDIR)/include
45 DEPENDPATH+= $(OPIEDIR)/include
46 TARGET = uqtreader
47 LIBS += -lqpe
48
diff --git a/noncore/apps/opie-reader/pdb.cpp b/noncore/apps/opie-reader/pdb.cpp
new file mode 100644
index 0000000..68b904e
--- a/dev/null
+++ b/noncore/apps/opie-reader/pdb.cpp
@@ -0,0 +1,57 @@
1#include "pdb.h"
2
3size_t Cpdb::recordpos(int n)
4{
5 UInt16 mxn = ntohs(head.recordList.numRecords);
6 if (n >= mxn)
7 {
8 return file_length;
9 }
10 else
11 {
12 size_t dataoffset = sizeof(DatabaseHdrType) - sizeof(UInt16);
13 dataoffset += /*dataoffset%4 + */ sizeof(RecordListType) * n;
14 fseek(fin, dataoffset, SEEK_SET);
15 RecordListType hdr;
16 fread(&hdr, 1, sizeof(hdr), fin);
17 return ntohl(hdr.nextRecordListID);
18 }
19
20}
21
22size_t Cpdb::recordlength(int n)
23{
24 return recordpos(n+1)-recordpos(n);
25}
26
27void Cpdb::gotorecordnumber(int n)
28{
29 fseek(fin, recordpos(n), SEEK_SET);
30}
31
32bool Cpdb::openfile(const char *src)
33{
34
35 // printf("In openfile\n");
36 int ret = 0;
37 // printf("closing fin:%x\n",fin);
38 if (fin != NULL) fclose(fin);
39 // printf("opening fin\n");
40 fin = fopen(src,"rb");
41
42 if (fin==0)
43 {
44 return false;
45 }
46
47 // just holds the first few chars of the file
48 //char buf[0x100];
49 fseek(fin,0,SEEK_END);
50 file_length = ftell(fin);
51
52 fseek(fin,0,SEEK_SET);
53
54 fread(&head, 1, sizeof(head), fin);
55
56 return true;
57}
diff --git a/noncore/apps/opie-reader/pdb.h b/noncore/apps/opie-reader/pdb.h
new file mode 100644
index 0000000..143c5cb
--- a/dev/null
+++ b/noncore/apps/opie-reader/pdb.h
@@ -0,0 +1,90 @@
1
2/*
3 * This header file defines some structures and types normally found in the
4 * Palm SDK. However, I don't want to require the presense of the SDK for a
5 * small utility since most Palm owners won't have it.
6 *
7 * $Id$
8 *
9 */
10
11#ifndef __PDB_H__
12#define __PDB_H__
13
14#include <netinet/in.h>
15#include <stdio.h>
16
17/* Normal Palm typedefs */
18typedef unsigned char UInt8;
19typedef unsigned short UInt16;
20typedef unsigned long UInt32;
21typedef UInt32 LocalID;
22
23/* Max length of DB name */
24#define dmDBNameLength 0x20
25
26
27/************************************************************
28 * Structure of a Record entry
29 *************************************************************/
30typedef struct {
31 LocalID localChunkID; // local chunkID of a record
32 UInt8 attributes; // record attributes;
33 UInt8 uniqueID[3]; // unique ID of record; should
34 // not be 0 for a legal record.
35} RecordEntryType;
36
37
38/************************************************************
39 * Structure of a record list extension. This is used if all
40 * the database record/resource entries of a database can't fit into
41 * the database header.
42 *************************************************************/
43typedef struct {
44 LocalID nextRecordListID; // local chunkID of next list
45 UInt16 numRecords; // number of records in this list
46 UInt16 firstEntry; // array of Record/Rsrc entries
47 // starts here
48} RecordListType;
49
50
51/************************************************************
52 * Structure of a Database Header
53 *************************************************************/
54typedef struct {
55 UInt8 name[dmDBNameLength]; // name of database
56 UInt16 attributes; // database attributes
57 UInt16 version; // version of database
58 UInt32 creationDate; // creation date of database
59 UInt32 modificationDate; // latest modification date
60 UInt32 lastBackupDate; // latest backup date
61 UInt32 modificationNumber; // modification number of database
62 LocalID appInfoID; // application specific info
63 LocalID sortInfoID; // app specific sorting info
64 UInt32 type; // database type
65 UInt32 creator; // database creator
66 UInt32 uniqueIDSeed; // used to generate unique IDs.
67 // Note that only the low order
68 // 3 bytes of this is used (in
69 // RecordEntryType.uniqueID).
70 // We are keeping 4 bytes for
71 // alignment purposes.
72 RecordListType recordList; // first record list
73} DatabaseHdrType;
74
75
76class Cpdb
77{
78 protected:
79 size_t file_length;
80 FILE* fin;
81 size_t recordpos(int);
82 size_t recordlength(int);
83 void gotorecordnumber(int);
84 DatabaseHdrType head;
85 bool openfile(const char* src);
86 Cpdb() : fin(NULL) {}
87 ~Cpdb() { if (fin != NULL) fclose(fin); }
88};
89#endif
90
diff --git a/noncore/apps/opie-reader/ppm.cpp b/noncore/apps/opie-reader/ppm.cpp
new file mode 100644
index 0000000..e8bf110
--- a/dev/null
+++ b/noncore/apps/opie-reader/ppm.cpp
@@ -0,0 +1,756 @@
1#include <stdlib.h>
2#include <stdio.h>
3#include "arith.h"
4#include "ppm.h"
5
6/****************************************************************************
7 * Gestion des noeuds
8 ****************************************************************************/
9
10/*
11 * Désallocation du noeud p
12 */
13
14void ppm_worker::Node_Free(UINT p) {
15 node_heap[node_free_last].free_next=p;
16 node_heap[p].free_next=NIL;
17 node_free_last=p;
18 node_free_nb++;
19}
20
21/*
22 * Allocation d'un noeud
23 * s'il ne reste plus de place, on désalloue le contexte le moins utilisé.
24 */
25
26UINT ppm_worker::Node_Alloc(void) {
27 UINT p;
28 if (node_free_nb<=2) Context_DeleteLast();
29 p=node_free_first;
30 node_free_first=node_heap[node_free_first].free_next;
31 node_free_nb--;
32#ifdef DEBUG
33 printf("Node_Alloc: p=%d\n",p);
34#endif
35 return p;
36}
37
38/****************************************************************************
39 * Gestion des contextes
40 ****************************************************************************/
41
42
43/*
44 * Mise au début de la liste des contextes du contexte c
45 */
46void ppm_worker::Context_MoveFirst(UINT c) {
47 NODE *ctx;
48
49 if (c!=ctx_first) {
50 ctx=&node_heap[c];
51 /* suppression du contexte dans la liste */
52 if (c==ctx_last) {
53 ctx_last=ctx->hdr.ctx_prev;
54 } else {
55 node_heap[ctx->hdr.ctx_prev].hdr.ctx_next=ctx->hdr.ctx_next;
56 node_heap[ctx->hdr.ctx_next].hdr.ctx_prev=ctx->hdr.ctx_prev;
57 }
58 /* insertion au début de la liste */
59 node_heap[ctx_first].hdr.ctx_prev=c;
60 ctx->hdr.ctx_next=ctx_first;
61 ctx_first=c;
62 }
63}
64
65/*
66 * Destruction du contexte le moins utilisé (ctx_last)
67 */
68void ppm_worker::Context_DeleteLast(void) {
69 NODE *n;
70 UINT h,h_next,node,node_next;
71 USHORT *p;
72
73 n=&node_heap[ctx_last];
74
75 /* libération dans la table de hachage. Comme on ne dispose pas de
76 * pointeur hash_prev dans les contextes, il faut parcourir toute
77 * la liste. Heureusement, celle-ci est de longueur faible en moyenne
78 */
79 h_next=n->hdr.hash_next;
80 h=h_next;
81 while (h<HASH_ADDRESS) h=node_heap[h].hdr.hash_next;
82 p=&hash_table[h-HASH_ADDRESS];
83 while (*p!=ctx_last) p=&node_heap[*p].hdr.hash_next;
84 *p=h_next;
85
86 /* libération des noeuds & modification de ctx_last */
87
88 if (n->hdr.sf_max>=2) {
89 node=n->hdr.sf.l.sf_next;
90 while (1) {
91 node_next=node_heap[node].sf.sf_next;
92 Node_Free(node);
93 if (node_next==NIL) break;
94 node=node_next;
95 }
96 }
97
98 node=ctx_last;
99 ctx_last=n->hdr.ctx_prev;
100 Node_Free(node);
101 ctx_nb--;
102}
103
104/*
105 * Création d'un nouveau contexte avec un seul symbole sym de fréquence 1
106 * Utilisation implicite de sym_context et sym_hash.
107 * Libération de mémoire si nécessaire, et mise en premier dans la liste
108 */
109void ppm_worker::Context_New(int sym,int order) {
110 NODE *ctx;
111 UINT i,c;
112
113#ifdef DEBUG
114 printf("Context_New: sym=%d o=%d\n",sym,order);
115#endif
116
117 c=Node_Alloc();
118 ctx=&node_heap[c];
119
120 /* mise du contexte en tête de la liste */
121 ctx->hdr.ctx_next=ctx_first;
122 node_heap[ctx_first].hdr.ctx_prev=c;
123 ctx_first=c;
124 ctx_nb++;
125
126 /* insertion dans la table de hachage */
127 ctx->hdr.hash_next=hash_table[sym_hash[order]];
128 hash_table[sym_hash[order]]=ctx_first;
129
130 /* initialisation du contexte */
131 ctx->hdr.order=order;
132 for(i=0;i<order;i++) ctx->hdr.sym[i]=sym_context[i+1];
133
134 ctx->hdr.sf_max=0;
135 ctx->hdr.sf.sf[0].sym=sym;
136 ctx->hdr.sf.sf[0].freq=1;
137#ifdef DEBUG
138 Context_Print(ctx_first);
139#endif
140}
141
142/*
143 * Ajout d'un nouveau symbole au contexte c
144 */
145
146void ppm_worker::Context_NewSym(int sym,UINT c) {
147 NODE *n,*m;
148 UINT p,sf_max;
149
150#ifdef DEBUG
151 printf("Context_NewSym: sym=%d c=%d\n",sym,c);
152 Context_Print(c);
153#endif
154
155 n=&node_heap[c];
156 sf_max=n->hdr.sf_max;
157 n->hdr.sf_max++;
158 if (sf_max==0) {
159 n->hdr.sf.sf[1].sym=sym;
160 n->hdr.sf.sf[1].freq=1;
161 } else if (sf_max==1) {
162 p=Node_Alloc();
163 m=&node_heap[p];
164 m->sf.sf[0]=n->hdr.sf.sf[0];
165 m->sf.sf[1]=n->hdr.sf.sf[1];
166 m->sf.sf[2].sym=sym;
167 m->sf.sf[2].freq=1;
168 m->sf.sf_next=NIL;
169 n->hdr.sf.l.sf_next=p;
170 n->hdr.sf.l.freq_tot=((UINT)m->sf.sf[0].freq+(UINT)m->sf.sf[1].freq+1);
171 } else {
172 n->hdr.sf.l.freq_tot++;
173 m=&node_heap[n->hdr.sf.l.sf_next];
174 while (sf_max>=NODE_SFNB) {
175 sf_max-=NODE_SFNB;
176 m=&node_heap[m->sf.sf_next];
177 }
178 sf_max++;
179 if (sf_max==NODE_SFNB) {
180 p=Node_Alloc();
181 m->sf.sf_next=p;
182 m=&node_heap[p];
183 m->sf.sf_next=NIL;
184 sf_max=0;
185 }
186 m->sf.sf[sf_max].sym=sym;
187 m->sf.sf[sf_max].freq=1;
188 }
189#ifdef DEBUG
190 Context_Print(c);
191#endif
192}
193
194
195#ifdef STAT
196int hash_nb=1;
197int hash_cnt=0;
198#endif
199
200/*
201 * Recherche d'un contexte, utilisation de façon implicite de sym_context
202 * et de sym_hash.
203 * C'est une procédure très critique qui doit être particulièrement optimisée
204 */
205
206UINT ppm_worker::Context_Search(int order) {
207 UCHAR *sym;
208 UINT i,p;
209 NODE *n;
210#ifdef DEBUG
211 printf("Context_Search: o=%d\n",order);
212#endif
213
214 p=hash_table[sym_hash[order]];
215 sym=&sym_context[1];
216#ifdef STAT
217 hash_nb++;
218#endif
219 while (p<HASH_ADDRESS) {
220#ifdef STAT
221 hash_cnt++;
222#endif
223 n=&node_heap[p];
224 if (n->hdr.order==order) {
225 if (order==0) return p;
226 i=0;
227 while (sym[i]==n->hdr.sym[i]) {
228 i++;
229 if (i==order) return p;
230 }
231 }
232 p=n->hdr.hash_next;
233 }
234 return HASH_ADDRESS;
235}
236
237/*
238 * Cette macro est HORRIBLE mais permet de simplifier beaucoup le parcours
239 * des listes de couples symbole,fréquence tout en ayant un code rapide.
240 * Une alternative élégante mais lente aurait été de passer une fonction
241 * en paramètre contenant le code à exécuter
242 */
243
244#define SF_Read(n,p,code_to_execute) \
245{\
246 UINT nb,i;\
247 nb=(UINT)n->hdr.sf_max+1;\
248 if (nb<=HDR_SFNB) {\
249 p=&n->hdr.sf.sf[0];\
250 } else {\
251 p=&node_heap[n->hdr.sf.l.sf_next].sf.sf[0];\
252 while (nb>NODE_SFNB) {\
253 for(i=0;i<NODE_SFNB;i++) {\
254 code_to_execute;\
255 p++;\
256 }\
257 p=&node_heap[ *((USHORT *)p) ].sf.sf[0];\
258 nb-=NODE_SFNB;\
259 }\
260 }\
261 for(i=0;i<nb;i++) {\
262 code_to_execute;\
263 p++;\
264 }\
265}
266
267
268/*
269 * Renormalisation d'un contexte, ie, division de toutes les fréquences
270 * par 2 et élimination des symboles de fréquence nulle
271 * Note: le contexte obtenu n'est jamais vide.
272 * Une amélioration prévue mais non implémentée serait de trier le contexte
273 * dans l'ordre des fréquences décroissantes pour accélérer la recherche.
274 * Les gains en vitesse seraient de toute façon assez faibles car les
275 * contextes sont de toute façon à peu près triés vu leur méthode de
276 * construction: les caractères sont ajoutés à la fin de la liste
277 */
278void ppm_worker::Context_Renorm(UINT ctx) {
279 NODE *n,*m;
280 UINT a,b,c,i,freq_tot,sf_nb;
281 SYMFREQ s,*p,tab_sf[SYM_NB];
282
283#ifdef DEBUG
284 printf("Context_Renorm: c=%d\n",ctx);
285 Context_Print(ctx);
286#endif
287
288 n=&node_heap[ctx];
289 freq_tot=0;
290 sf_nb=0;
291
292 SF_Read(n,p, {
293 s=*p;
294 s.freq=s.freq/2;
295 if (s.freq!=0) {
296 freq_tot+=s.freq;
297 tab_sf[sf_nb]=s;
298 sf_nb++;
299 }
300 } );
301
302
303 /* libération des noeuds utilisés pour stocker les symboles */
304 if (n->hdr.sf_max>=HDR_SFNB) {
305 a=n->hdr.sf.l.sf_next;
306 do {
307 b=node_heap[a].sf.sf_next;
308 Node_Free(a);
309 a=b;
310 } while (a!=NIL);
311 }
312
313 /* reconstruction de la liste des "sf_nb" symboles d'apres le tableau
314 * "tab_sf"
315 */
316
317 n->hdr.sf_max=sf_nb-1;
318 if (sf_nb<=HDR_SFNB) {
319 for(i=0;i<sf_nb;i++) n->hdr.sf.sf[i]=tab_sf[i];
320 } else {
321 a=Node_Alloc();
322 n->hdr.sf.l.sf_next=a;
323 n->hdr.sf.l.freq_tot=freq_tot;
324 m=&node_heap[a];
325 i=0;
326 c=0;
327 while (1) {
328 m->sf.sf[c]=tab_sf[i];
329 i++;
330 if (i==sf_nb) break;
331 c++;
332 if (c==NODE_SFNB) {
333 c=0;
334 a=Node_Alloc();
335 m->sf.sf_next=a;
336 m=&node_heap[a];
337 }
338 }
339 m->sf.sf_next=NIL;
340 }
341
342#ifdef DEBUG
343 Context_Print(ctx);
344#endif
345}
346
347
348/*
349 * Mise à jour des index dans la table de hachage et des caractères du
350 * contexte courant.
351 * La fonction de hachage a été choisie de façon empirique en controlant
352 * qu'elle donne en moyenne de bons résultats.
353 */
354void ppm_worker::Hash_Update(int sym) {
355 UINT i,k;
356
357 for(i=ORDER_MAX;i>=2;i--)
358 sym_context[i]=sym_context[i-1];
359 sym_context[1]=sym;
360
361 for(i=ORDER_MAX;i>=2;i--) {
362 k=sym_hash[i-1];
363 sym_hash[i]=( (k<<6)-k+sym ) & (HASH_SIZE-1);
364 }
365 sym_hash[1]=sym+1;
366}
367
368
369/****************************************************************************
370 * Système d'exclusion des symboles
371 ****************************************************************************/
372
373
374/*
375 * Remise à zéro du tableau d'exclusion des symboles
376 */
377void ppm_worker::Sym_ExcludeReset(void) {
378 UINT i;
379
380 sym_excl_code++;
381 if (sym_excl_code==0) {
382 for(i=0;i<SYM_NB;i++) sym_excl[i]=0;
383 sym_excl_code=1;
384 }
385}
386
387
388/****************************************************************************
389 * Initialisation et Libération mémoire
390 ****************************************************************************/
391
392/*
393 * Initialisation des structures de données du compresseur/décompresseur
394 * retourne 0 si tout va bien
395 */
396int ppm_worker::PPM_Init(unsigned short NODE_NBMAX) {
397 UINT i;
398 node_heap= new NODE[NODE_NBMAX];
399 hash_table= new USHORT[HASH_SIZE];
400 if (node_heap==NULL || hash_table==NULL) {
401 if (node_heap!=NULL) delete [] node_heap;
402 if (hash_table!=NULL) delete [] hash_table;
403 return 1;
404 }
405 /* noeuds: tous vides */
406 for(i=0;i<=(NODE_NBMAX-2);i++) node_heap[i].free_next=i+1;
407 node_heap[NODE_NBMAX-1].free_next=NIL;
408 node_free_first=0;
409 node_free_last=NODE_NBMAX-1;
410 node_free_nb=NODE_NBMAX;
411
412 /* contextes */
413 for(i=0;i<HASH_SIZE;i++) hash_table[i]=HASH_ADDRESS+i;
414
415 /* cette initialisation n'est pas sûre mais simplifie beaucoup le code:
416 * on suppose que le premier contexte sera alloué dans le noeud 0
417 */
418 ctx_first=0;
419 ctx_last=0;
420 ctx_nb=0;
421
422 /* contexte courant */
423 for(i=0;i<=ORDER_MAX;i++) sym_context[i]=0;
424 for(i=0;i<=ORDER_MAX;i++) sym_hash[i]=0;
425
426 /* système d'exclusion des caractères */
427 sym_excl_code=0xFF;
428
429 return 0;
430}
431
432/*
433 * Fin de la compression/décompression: on libère la mémoire
434 */
435void ppm_worker::PPM_End(void) {
436 free(hash_table);
437 free(node_heap);
438}
439
440/****************************************************************************
441 * Décodage et décompression
442 ****************************************************************************/
443
444/*
445 * Décodage: cf Encode_NewSym
446 */
447int ppm_worker::Decode_NewSym(void) {
448 UINT i,freq_tot,freq_cum,f;
449 UCHAR code;
450
451 code=sym_excl_code;
452 freq_tot=0;
453 for(i=0;i<SYM_NB;i++) if (sym_excl[i]!=code) freq_tot++;
454 f=arith.Arith_DecodeVal(freq_tot+SYM_SPECIAL_NB);
455 if (f>=freq_tot) {
456 /* cas d'un symbole spécial */
457 arith.Arith_Decode(f,f+1,freq_tot+SYM_SPECIAL_NB);
458 return SYM_NB+f-freq_tot;
459 } else {
460 i=0;
461 freq_cum=0;
462 while (1) {
463 if (sym_excl[i]!=code) {
464 freq_cum++;
465 if (freq_cum>f) break;
466 }
467 i++;
468 }
469 arith.Arith_Decode(freq_cum-1,freq_cum,freq_tot+SYM_SPECIAL_NB);
470 return i;
471 }
472}
473
474/*
475 * Décodage: cf Decode_NoExclude
476 */
477int ppm_worker::Decode_NoExclude(UINT ctx) {
478 NODE *n;
479 UCHAR code;
480 UINT i,f,freq_tot,freq_cum,freq_sym,sf_nb;
481 SYMFREQ *p,s;
482
483
484 n=&node_heap[ctx];
485 code=sym_excl_code;
486
487 /* Calcul de la somme des fréquences des caractères */
488 if (n->hdr.sf_max<HDR_SFNB) {
489 freq_tot=0;
490 for(i=0;i<=n->hdr.sf_max;i++) freq_tot+=n->hdr.sf.sf[i].freq;
491 } else {
492 freq_tot=n->hdr.sf.l.freq_tot;
493 }
494
495 /* décodage */
496 sf_nb=(UINT) n->hdr.sf_max+1;
497 f=arith.Arith_DecodeVal(freq_tot+sf_nb);
498 if (f>=freq_tot) {
499 /* gestion du code ESCAPE */
500
501 /* marquage des caractères utilisés */
502 SF_Read(n,p, { sym_excl[p->sym]=code; });
503
504 /* décodage ESCAPE */
505 arith.Arith_Decode(freq_tot,freq_tot+sf_nb,freq_tot+sf_nb);
506 return SYM_ESCAPE;
507 }
508
509 /* recherche du caractère en calculant la fréquence */
510 freq_cum=0;
511 SF_Read(n,p, {
512 s=*p;
513 freq_cum+=s.freq;
514 if (freq_cum>f) goto decode_sym;
515 } );
516
517 decode_sym:
518
519 freq_sym=s.freq;
520 p->freq=freq_sym+1;
521 if (n->hdr.sf_max>=HDR_SFNB) n->hdr.sf.l.freq_tot=freq_tot+1;
522
523 arith.Arith_Decode(freq_cum-freq_sym,freq_cum,freq_tot+sf_nb);
524
525 /* test de la renormalisation */
526 if (freq_sym==(RENORM_FREQSYM-1) || freq_tot>=RENORM_FREQTOT) {
527 Context_Renorm(ctx);
528 }
529 return s.sym;
530}
531
532
533/*
534 * Décodage: cf Encode_Exclude
535 */
536
537int ppm_worker::Decode_Exclude(UINT ctx) {
538 UINT sf_nb,freq_sym,freq_cum,freq_tot,f;
539 NODE *n;
540 SYMFREQ s,*p;
541 UCHAR code;
542
543 n=&node_heap[ctx];
544 code=sym_excl_code;
545
546 freq_tot=0;
547 sf_nb=0;
548
549 SF_Read( n,p, {
550 s=*p;
551 if (sym_excl[s.sym]!=code)
552 {
553 freq_tot+=s.freq;
554 sf_nb++;
555 }
556 } );
557
558
559 f=arith.Arith_DecodeVal(freq_tot+sf_nb);
560
561 if (f>=freq_tot) {
562
563 /* ESCAPE */
564
565 SF_Read(n,p, { sym_excl[p->sym]=code; } );
566
567 arith.Arith_Decode(freq_tot,freq_tot+sf_nb,freq_tot+sf_nb);
568
569 return SYM_ESCAPE;
570 } else {
571
572 /* recherche du caractère */
573
574 freq_cum=0;
575 SF_Read(n,p, {
576 s=*p;
577 if (sym_excl[s.sym]!=code) {
578 freq_cum+=s.freq;
579 if (freq_cum>f) goto decode_sym;
580 }
581 } );
582
583 decode_sym:
584
585 /* incrémentation de la fréquence */
586
587 freq_sym=p->freq;
588 p->freq=freq_sym+1;
589 if (n->hdr.sf_max>=HDR_SFNB) n->hdr.sf.l.freq_tot++;
590
591 /* décodage du caractère */
592
593 arith.Arith_Decode(freq_cum-freq_sym,freq_cum,freq_tot+sf_nb);
594
595 if (freq_sym==(RENORM_FREQSYM-1) || freq_tot>=RENORM_FREQTOT) {
596 Context_Renorm(ctx);
597 }
598
599 return s.sym;
600 }
601}
602
603
604/*
605 * Décodage d'un symbole
606 */
607int ppm_worker::PPM_Decode(void) {
608 int i,order,sym;
609 UINT ctx,ctx_tab[ORDER_MAX+1],ctx_last;
610
611
612 /* recherche de l'ordre maximum */
613
614 Sym_ExcludeReset();
615 order=ORDER_MAX;
616 ctx_last=NIL;
617 while (1) {
618 ctx=Context_Search(order);
619 ctx_tab[order]=ctx;
620 if (ctx<HASH_ADDRESS) {
621 Context_MoveFirst(ctx);
622 if (ctx_last==NIL)
623 sym=Decode_NoExclude(ctx);
624 else
625 sym=Decode_Exclude(ctx);
626 if (sym!=SYM_ESCAPE) break;
627 ctx_last=ctx;
628 }
629 order--;
630 if (order==-1) {
631 sym=Decode_NewSym();
632 if (sym>=SYM_NB) return sym;
633 break;
634 }
635 }
636
637 for(i=order+1;i<=ORDER_MAX;i++) {
638 if (ctx_tab[i]>=HASH_ADDRESS)
639 Context_New(sym,i);
640 else
641 Context_NewSym(sym,ctx_tab[i]);
642 }
643
644 Hash_Update(sym);
645
646 return sym;
647}
648
649/*
650 * Décompression: idem
651 */
652
653#ifdef STAT
654
655/****************************************************************************
656 * Statistiques
657 ****************************************************************************/
658
659
660void ppm_worker::PrintStat(void) {
661 fprintf(stderr,"free=%d ctx_nb=%d hash_moy=%0.2f\n",
662 node_free_nb,ctx_nb,
663 (float)hash_cnt/(float)hash_nb);
664
665}
666
667/*
668 * Impression d'un caractère
669 */
670void ppm_worker::Sym_Print(int c) {
671 if (c>=32 && c<=126) printf("%c",c); else printf("\\%2X",c);
672}
673
674/*
675 * Impression couple SYMFREQ
676 */
677
678void ppm_worker::SF_Print(SYMFREQ s) {
679 Sym_Print(s.sym);
680 printf(":%d ",s.freq);
681}
682
683/*
684 * Impression du contenu d'un contexte
685 * utilisé pour les tests
686 */
687
688void ppm_worker::Context_Print(UINT c) {
689 NODE *n;
690 int i,sf_max,sf_nb,sf_freq;
691
692 n=&node_heap[c];
693
694 sf_max=n->hdr.sf_max;
695 sf_nb=sf_max+1;
696 if (sf_max>=2) sf_freq=n->hdr.sf.l.freq_tot;
697 else {
698 sf_freq=0;
699 for(i=0;i<=sf_max;i++) sf_freq+=n->hdr.sf.sf[i].freq;
700 }
701
702 printf("Ctx=%d: hash_n=%d ctx_p=%d ctx_n=%d o=%d sf_nb=%d sf_freq=%d\n",
703 c,n->hdr.hash_next,n->hdr.ctx_prev,n->hdr.ctx_next,
704 n->hdr.order,sf_nb,sf_freq);
705 for(i=0;i<n->hdr.order;i++) Sym_Print(n->hdr.sym[i]);
706 printf(": ");
707 if (sf_max<=1) {
708 for(i=0;i<=sf_max;i++) SF_Print(n->hdr.sf.sf[i]);
709 } else {
710 n=&node_heap[n->hdr.sf.l.sf_next];
711 i=0;
712 while (1) {
713 SF_Print(n->sf.sf[i]);
714 if (sf_max==0) break;
715 i++;
716 sf_max--;
717 if (i==NODE_SFNB) {
718 i=0;
719 n=&node_heap[n->sf.sf_next];
720 }
721 }
722 }
723 printf("\n");
724}
725
726
727/*
728 * Nombre total de contextes et nombre de contextes de longueur données.
729 * Utilisé pour les statistiques
730 */
731
732void ppm_worker::Context_Statistic(void) {
733 UINT i,p;
734 int tab[SYM_NB+1],tot,cnt;
735
736 for(i=0;i<=SYM_NB;i++) tab[i]=0;
737 tot=0;
738
739 p=ctx_first;
740 do {
741 cnt=node_heap[p].hdr.sf_max+1;
742 tab[cnt]++;
743 tot++;
744 p=node_heap[p].hdr.ctx_next;
745 } while (p!=ctx_last);
746
747
748 printf("Context_Statistic: ");
749 for(i=1;i<=SYM_NB;i++) {
750 printf("%d:%d (%0.2f%%),",i,tab[i],(float)tab[i]/(float)tot*100.0);
751 }
752 printf("\n");
753}
754
755#endif
756
diff --git a/noncore/apps/opie-reader/ppm.h b/noncore/apps/opie-reader/ppm.h
new file mode 100644
index 0000000..4df9085
--- a/dev/null
+++ b/noncore/apps/opie-reader/ppm.h
@@ -0,0 +1,179 @@
1#include "utypes.h"
2
3#ifndef PPM_H
4
5#define PPM_H
6
7#include "arith.h"
8
9/* pour le calcul éventuel de quelques statistiques */
10/* #define STAT */
11
12/* mise en mode debogage */
13/* #define DEBUG */
14
15/* nombre de noeuds maximum: peut être modifié, mais doit être tel que:
16 * HASH_SIZE+NODE_NBMAX<65530
17 */
18//#define NODE_NBMAX 40000
19
20/*
21 * taille des buffers d'entrée/sortie
22 */
23#define BUFSIZE 1024
24
25/*
26 * Taille de la table de hachage
27 */
28#define HASH_SIZE 16384
29
30/* ordre maximale de prédiction utilisé (Phi) */
31#define ORDER_MAX 4
32
33/* fréquence maximale d'un symbole */
34#define RENORM_FREQSYM 250
35
36/* fréquence maximale pour la somme des fréquences des symboles d'un contexte */
37#define RENORM_FREQTOT 15000
38
39/* nombre de couples symbole,fréquence dans les structures de noeuds
40 * ajusté pour faire au total 16 octets */
41#define NODE_SFNB 7
42#define HDR_SFNB 2
43
44/* nombre de symboles à coder sans compter les symboles spéciaux */
45#define SYM_NB 256
46
47/* nombre de symboles spéciaux: pour extension si besoin de signalisation */
48#define SYM_SPECIAL_NB 1
49
50/* code associé au symbole ESCAPE (jamais codé de façon explicite) */
51#define SYM_ESCAPE 256
52
53/* code de fin de fichier */
54#define SYM_EOF 256
55
56/* valeur NULL pour les pointeurs stockés dans des USHORT */
57#define NIL 0xFFFF
58
59/* codage de NIL utilisé pour retrouver l'adresse dans la table de hachage
60 * d'un contexte en regardant seulement CTXHDR.hash_next */
61#define HASH_ADDRESS (65530-HASH_SIZE)
62
63
64/* stockage d'un couple symbole, fréquence */
65typedef struct {
66 UCHAR sym; /* numéro du symbole */
67 UCHAR freq; /* fréquence du symbole */
68} SYMFREQ;
69
70
71/* header pour gérer un contexte */
72typedef struct {
73 USHORT ctx_next; /* contexte suivant (moins utilisé) */
74 USHORT ctx_prev; /* contexte précédent (plus utilisé) */
75 USHORT hash_next; /* contexte suivant dans une entrée de la table
76 * de hachage */
77 UCHAR order; /* ordre du contexte */
78 UCHAR sym[ORDER_MAX]; /* symboles constituant le contexte */
79 UCHAR sf_max; /* nombre de symboles-1 dans la liste L */
80 union {
81 SYMFREQ sf[HDR_SFNB]; /* s'il y a moins de HDR_SFNB symboles dans
82 * le contexte, on les stocke directement ici
83 */
84 struct {
85 USHORT freq_tot; /* sinon on stocke la fréquence totale (c) */
86 USHORT sf_next; /* et un pointeur sur le premier noeud
87 * constituant la liste L des symboles associés
88 * au contexte */
89 } l;
90 } sf;
91} CTXHDR;
92
93/* structure pour gérer NODE_SFNB éléments de la liste des symboles associés
94 * à un contexte */
95typedef struct {
96 SYMFREQ sf[NODE_SFNB]; /* les couples symbole, fréquence */
97 USHORT sf_next; /* pointeur sur l'éventuel bloc suivant */
98} CTXSYMFREQ;
99
100/*
101 * structure de base pour la gestion de la mémoire: le noeud
102 */
103
104typedef union _NODE {
105 CTXHDR hdr; /* si le noeud contient un header de contexte */
106 CTXSYMFREQ sf; /* si le noeud contient une partie de la liste L */
107 USHORT free_next; /* si le noeud est vide: pointeur sur un noeud vide
108 * suivant */
109} NODE;
110
111class ppm_worker
112{
113
114/* gestion des noeuds */
115NODE *node_heap; /* heap contenant tous les noeuds */
116UINT node_free_nb; /* nombre de noeuds vides */
117UINT node_free_first; /* premier noeud de la liste des noeuds vides */
118UINT node_free_last; /* dernier noeud de la liste des noeuds vides */
119
120/* gestion de la liste des contextes les plus utilisés */
121USHORT *hash_table; /* table de hachage pour rechercher un contexte */
122UINT ctx_first; /* premier contexte: le plus utilisé */
123UINT ctx_last; /* dernier contexte: le moins utilisé */
124UINT ctx_nb; /* nombre de contextes */
125
126/* données caractérisant le contexte courant */
127UCHAR sym_context[ORDER_MAX+1]; /* symboles précédants le symbole en cours
128 * de codage */
129int sym_hash[ORDER_MAX+1]; /* index dans la table de hachage
130 * correspondants aux différentes longueurs
131 * de contextes
132 */
133
134/* système d'exclusion des caractères */
135UCHAR sym_excl[SYM_NB]; /* tableau pour l'exclusion */
136UCHAR sym_excl_code; /* code courant pour l'exclusion */
137
138
139/* déclaration des fonctions de base */
140
141/* noeuds */
142void Node_Free(UINT p);
143UINT Node_Alloc(void);
144
145/* contextes */
146void Context_DeleteLast(void);
147void Context_MoveFirst(UINT c);
148void Context_New(int sym,int order);
149void Context_NewSym(int sym,UINT c);
150UINT Context_Search(int order);
151void Context_Renorm(UINT ctx);
152void Hash_Update(int sym);
153 void Sym_ExcludeReset(void);
154
155/* codage */
156/*
157void Encode_NewSym(int sym);
158int Encode_NoExclude(int sym,UINT ctx);
159int Decode_Exclude(UINT ctx);
160int PPM_Decode(void);
161*/
162
163/* décodage */
164int Decode_NewSym(void);
165int Decode_NoExclude(UINT ctx);
166int Decode_Exclude(UINT ctx);
167
168#ifdef STAT
169void PrintStat(void);
170#endif
171 public:
172 ArithClass arith;
173 int PPM_Init(unsigned short);
174 void PPM_End(void);
175 int PPM_Decode(void);
176};
177
178#endif
179
diff --git a/noncore/apps/opie-reader/ppm_expander.cpp b/noncore/apps/opie-reader/ppm_expander.cpp
new file mode 100644
index 0000000..4f0a277
--- a/dev/null
+++ b/noncore/apps/opie-reader/ppm_expander.cpp
@@ -0,0 +1,108 @@
1/*
2 * Interface pour le programme de compression
3 * (c) 1995 Fabrice Bellard
4 */
5
6#include <stdlib.h>
7//#include <unistd.h>
8#include <stdio.h>
9#include <string.h>
10#include <time.h>
11
12/***************************************************************************
13 * Interface avec les routines de compression
14 */
15
16#define METHOD_NB 2 /* nombre total de méthodes de compression */
17
18#define METHOD_STORE 0
19#define METHOD_PPM 1
20
21
22#define DEFAULT_SUFFIX ".st" /* extension par défault */
23/* signature en début de fichier */
24#define STAT_MAGIC_SIZE 4
25char stat_magic[STAT_MAGIC_SIZE]={'P','P','M','S'};
26
27#include "ppm_expander.h"
28
29ppm_expander::~ppm_expander() {
30 if (needppmend) ppm.PPM_End();
31 ppm.arith.Arith_DecodeEnd();
32 if (buf_in!=NULL) delete [] buf_in;
33 if (buf_out!=NULL) delete [] buf_out;
34 if (my_read_buf != NULL) delete my_read_buf;
35 if (my_file_in != NULL) fclose(my_file_in);
36}
37
38int ppm_expander::openfile(const char* infile)
39{
40 my_file_in=fopen(infile,"rb");
41 my_read_buf = new PPM_ReadBuf(my_file_in);
42 return home();
43}
44
45void ppm_expander::sizes(unsigned long& file, unsigned long& text)
46{
47 struct stat _stat;
48 fstat(fileno(my_file_in),&_stat);
49 file = _stat.st_size;
50 text = numblocks*blocksize;
51}
52
53int ppm_expander::home()
54{
55 fseek(my_file_in,0, SEEK_SET);
56 unsigned char header[STAT_MAGIC_SIZE];
57 size_t len=fread(header,1,STAT_MAGIC_SIZE,my_file_in);
58 if (strncmp((char*)header,stat_magic,STAT_MAGIC_SIZE)!=0) {
59 return 1;
60 }
61 if (len!=(STAT_MAGIC_SIZE)) {
62 return 1;
63 }
64 if (fread(&maxnode,sizeof(maxnode),1,my_file_in) != 1) return 1;
65 if (fread(&blocksize,sizeof(blocksize),1,my_file_in) != 1) return 1;
66 if (fread(&numblocks,sizeof(numblocks),1,my_file_in) != 1) return 1;
67 //fprintf(stderr,"<%u,%u,%u>\n",maxnode,blocksize,numblocks);
68 int err = locate(0,0);
69 outbytes = 0;
70 return err;
71}
72
73void ppm_expander::locate(unsigned int n) {
74 locate(n/blocksize, n%blocksize);
75 outbytes = n;
76}
77
78int ppm_expander::locate(unsigned short block, unsigned int n)
79{
80 if (needppmend)
81 {
82 ppm.PPM_End();
83 needppmend = false;
84 }
85 size_t fpos;
86 fseek(my_file_in,STAT_MAGIC_SIZE+sizeof(maxnode)+sizeof(blocksize)+sizeof(numblocks)+block*sizeof(fpos),SEEK_SET);
87 if (fread(&fpos,sizeof(fpos),1,my_file_in) != 1) return 1;
88 fseek(my_file_in,fpos,SEEK_SET);
89
90 ppm.arith.Arith_DecodeInit(my_read_buf,buf_in,bufsize);
91 int err=ppm.PPM_Init(maxnode);
92 needppmend = true;
93 curblock = block;
94 for (int i = 0; i < n; i++) getch();
95}
96
97int ppm_expander::getch() {
98 if (curblock >= numblocks) return EOF;
99 int c=ppm.PPM_Decode();
100 if (c == SYM_EOF)
101 {
102 if (++curblock >= numblocks) return EOF;
103 locate(curblock,0);
104 c = ppm.PPM_Decode();
105 }
106 outbytes++;
107 return (c==SYM_EOF) ? EOF : c;
108}
diff --git a/noncore/apps/opie-reader/ppm_expander.h b/noncore/apps/opie-reader/ppm_expander.h
new file mode 100644
index 0000000..ce95db7
--- a/dev/null
+++ b/noncore/apps/opie-reader/ppm_expander.h
@@ -0,0 +1,46 @@
1#ifndef __ppm_expander_h
2#define __ppm_expander_h
3
4#include "CExpander.h"
5#include <sys/stat.h>
6
7
8#include "utypes.h"
9#include "ppm.h"
10#include "arith.h"
11
12
13#define SYM_EOF 256
14
15class ppm_expander : public CExpander {
16 UCHAR *buf_in,*buf_out;
17 unsigned int bufsize;
18 unsigned int outbytes;
19 unsigned long blocksize;
20 unsigned short numblocks;
21 unsigned short curblock;
22 unsigned short maxnode;
23 bool needppmend;
24 int home();
25 FILE* my_file_in;
26 PPM_ReadBuf* my_read_buf;
27 ppm_worker ppm;
28 public:
29 ppm_expander() : needppmend(false), my_file_in(NULL), my_read_buf(NULL)
30 {
31 bufsize = 1024;
32 buf_in = new UCHAR[bufsize];
33 buf_out = new UCHAR[bufsize];
34 outbytes = 0;
35 }
36 virtual int openfile(const char* infile);
37 virtual int getch();
38 int locate(unsigned short block, unsigned int n);
39 virtual ~ppm_expander();
40 virtual unsigned int locate() { return outbytes; }
41 virtual void locate(unsigned int n);
42 virtual bool hasrandomaccess() { return (numblocks > 1); }
43 virtual void sizes(unsigned long& file, unsigned long& text);
44};
45
46#endif
diff --git a/noncore/apps/opie-reader/update.sh b/noncore/apps/opie-reader/update.sh
new file mode 100755
index 0000000..05dc175
--- a/dev/null
+++ b/noncore/apps/opie-reader/update.sh
@@ -0,0 +1,11 @@
1#!/bin/bash
2cp /home/tim/uqtreader/uqtreader.desktop /opt/Qtopia/apps/Applications/
3cp /home/tim/bin/uqtreader /opt/Qtopia/bin/
4cp /home/tim/uqtreader/uqtreader.png /opt/Qtopia/pics/
5cp /home/tim/qtreader/panel-arrow-down.png /opt/Qtopia/pics/
6cp /home/tim/uqtreader/uqtreader.desktop /opt/Qtopia/sharp/apps/Applications/
7cp /home/tim/bin/uqtreader /opt/Qtopia/sharp/bin/
8cp /home/tim/uqtreader/uqtreader.png /opt/Qtopia/sharp/pics/
9cp /home/tim/qtreader/panel-arrow-down.png /opt/Qtopia/sharp/pics/
10#source /home/tim/bin/setz.sh
11#mkipks qpe-qtreader.control
diff --git a/noncore/apps/opie-reader/ustring.h b/noncore/apps/opie-reader/ustring.h
new file mode 100644
index 0000000..a4dc048
--- a/dev/null
+++ b/noncore/apps/opie-reader/ustring.h
@@ -0,0 +1,71 @@
1#include <qstring.h>
2
3#ifdef _UNICODE
4inline size_t ustrlen(const tchar* _p)
5{
6 if (_p == NULL) return 0;
7 const tchar *p = _p;
8 while (*p != 0)
9 {
10 p++;
11/*
12 if (p - _p == 20)
13 {
14 printf("ustrlen::String too long:");
15 for (int i = 0; i < 20; i++) printf("%c",_p[i]);
16 printf("\n");
17 }
18*/
19 }
20 return p - _p;
21}
22
23inline int ustrcmp(const tchar* _p1, const tchar* _p2)
24{
25 if (_p1 == 0) return 1;
26 if (_p2 == 0) return -1;
27 const tchar* p1 = _p1, *p2 = _p2;
28 while (*p1 != 0)
29 {
30/*
31 if (p1 - _p1 == 20)
32 {
33 printf("ustrcmp::String too long:");
34 for (int i = 0; i < 20; i++) printf("%c",_p1[i]);
35 printf("\n");
36 }
37*/
38 if (*p1 < *p2) return -1;
39 if (*p1 > *p2) return 1;
40 if (*p2 == 0) return 1;
41 p1++, p2++;
42 }
43 if (*p2 != 0) return -1;
44 return 0;
45}
46
47inline QString toQString(tchar *_p)
48{
49 if (_p == NULL) return 0;
50 int i = 0;
51 tchar *p = _p;
52 QString ret;
53 while (*p != 0) ret[i++] = *(p++);
54 return ret;
55}
56
57inline QString toQString(tchar *_p, unsigned int len)
58{
59 if (_p == NULL) return 0;
60 unsigned int i = 0;
61 tchar *p = _p;
62 QString ret;
63 while (*p != 0 && i < len) ret[i++] = *(p++);
64 return ret;
65}
66#else
67
68inline size_t ustrlen(const tchar* _p) { return strlen(_p); }
69inline int ustrcmp(const tchar* _p1, const tchar* _p2) { return strcmp(_p1, _p2); }
70
71#endif
diff --git a/noncore/apps/opie-reader/utypes.h b/noncore/apps/opie-reader/utypes.h
new file mode 100644
index 0000000..b7c59f3
--- a/dev/null
+++ b/noncore/apps/opie-reader/utypes.h
@@ -0,0 +1,14 @@
1/*
2 * Quelques types utiles
3 */
4
5#ifndef UTYPES_H
6
7#define UTYPES_H
8
9typedef unsigned char UCHAR;
10typedef unsigned short USHORT;
11typedef unsigned int UINT;
12
13#endif
14
diff --git a/noncore/apps/opie-reader/version.h b/noncore/apps/opie-reader/version.h
new file mode 100644
index 0000000..bd32e4d
--- a/dev/null
+++ b/noncore/apps/opie-reader/version.h
@@ -0,0 +1,3 @@
1#define MAJOR "0"
2#define MINOR "3r"
3#define RELEASE_TYPE "beta(U)"
diff --git a/noncore/apps/opie-reader/ztxt.cpp b/noncore/apps/opie-reader/ztxt.cpp
new file mode 100644
index 0000000..c30e4fd
--- a/dev/null
+++ b/noncore/apps/opie-reader/ztxt.cpp
@@ -0,0 +1,159 @@
1#include <stdio.h>
2#include <string.h>
3#include "ztxt.h"
4
5ztxt::ztxt() : bInit(false), expandedtextbuffer(NULL), compressedtextbuffer(NULL) { /*printf("constructing:%x\n",fin);*/ }
6
7
8int ztxt::openfile(const char *src)
9{
10 if (!Cpdb::openfile(src))
11 {
12 return -1;
13 }
14
15//printf("Okay %u\n", 4);
16
17 if (head.type != ZTXT_ID) return -1;
18
19 gotorecordnumber(0);
20 fread(&hdr0, 1, sizeof(hdr0), fin);
21//printf("Okay %u\n", 5);
22 buffersize = ntohl(hdr0.size);
23 compressedtextbuffer = new UInt8[buffersize];
24 expandedtextbuffer = new UInt8[buffersize];
25//printf("Okay %u\n", 6);
26
27 home();
28//printf("Okay %u\n", 7);
29
30// printf("Returning 0\n");
31
32 return 0;
33}
34
35int ztxt::getch()
36{
37 if (bufferpos >= buffercontent)
38 {
39 size_t reclen = recordlength(++bufferrec);
40 if (reclen == 0) return -1;
41 gotorecordnumber(bufferrec);
42 fread(compressedtextbuffer, reclen, sizeof(char), fin);
43
44 zstream.next_in = compressedtextbuffer;
45 zstream.next_out = expandedtextbuffer;
46 zstream.avail_out = buffersize;
47 zstream.avail_in = reclen;
48
49 int ret = inflate(&zstream, Z_SYNC_FLUSH);
50 buffercontent = buffersize - zstream.avail_out;
51 bufferpos = 0;
52
53 }
54 currentpos++;
55 return expandedtextbuffer[bufferpos++];
56}
57
58unsigned int ztxt::locate()
59{
60 return currentpos;
61}
62
63void ztxt::locate(unsigned int n)
64{
65
66 if (hasrandomaccess())
67 {
68 bufferrec = n / ntohs(hdr0.recordSize) + 1;
69 if (bufferrec == 1)
70 {
71 inflateEnd(&zstream);
72 }
73 size_t reclen = recordlength(bufferrec);
74 if (reclen == 0) return;
75 gotorecordnumber(bufferrec);
76 fread(compressedtextbuffer, reclen, sizeof(char), fin);
77
78 zstream.next_in = compressedtextbuffer;
79 zstream.next_out = expandedtextbuffer;
80 zstream.avail_out = buffersize;
81 zstream.avail_in = reclen;
82
83 if (bufferrec == 1)
84 {
85 zstream.zalloc = Z_NULL;
86 zstream.zfree = Z_NULL;
87 zstream.opaque = Z_NULL;
88
89 inflateInit(&zstream);
90 }
91
92
93 int ret = inflate(&zstream, Z_SYNC_FLUSH);
94 buffercontent = buffersize - zstream.avail_out;
95 bufferpos = 0;
96 currentpos = n - n % ntohs(hdr0.recordSize);
97 while (currentpos < n) getch();
98 }
99 else
100 {
101 home();
102 while (currentpos < n && getch() != EOF);
103 }
104}
105
106void ztxt::home()
107{
108 if (bInit)
109 {
110 inflateEnd(&zstream);
111 }
112 bInit = true;
113 size_t reclen = recordlength(1);
114 gotorecordnumber(1);
115 fread(compressedtextbuffer, reclen, sizeof(char), fin);
116
117 zstream.next_in = compressedtextbuffer;
118 zstream.next_out = expandedtextbuffer;
119 zstream.avail_out = buffersize;
120 zstream.avail_in = reclen;
121
122 zstream.zalloc = Z_NULL;
123 zstream.zfree = Z_NULL;
124 zstream.opaque = Z_NULL;
125
126// printf("Initialising\n");
127
128 inflateInit(&zstream);
129
130 int ret = inflate(&zstream, Z_SYNC_FLUSH);
131// printf("Inflate : %d\n", ret);
132 bufferpos = 0;
133 bufferrec = 1;
134 currentpos = 0;
135 buffercontent = buffersize - zstream.avail_out;
136 //printf("buffercontent:%u\n", buffercontent);
137}
138
139CList<Bkmk>* ztxt::getbkmklist()
140{
141 UInt16 recno = ntohs(hdr0.bookmarkRecord);
142
143// printf("Bookmarks - record %d contains %d\n", recno, ntohs(hdr0.numBookmarks));
144
145 if (recno == 0) return NULL;
146
147 CList<Bkmk>* t = new CList<Bkmk>;
148 size_t cur = ftell(fin);
149 gotorecordnumber(recno);
150 for (int i = 0; i < ntohs(hdr0.numBookmarks); i++)
151 {
152 zTXTbkmk bkmk;
153 if (fread(&bkmk, sizeof(bkmk), 1, fin) != 1) break;
154// printf("Bookmark number:%d:%.20s\n", i, bkmk.title);
155 t->push_back(Bkmk(bkmk.title, ntohl(bkmk.offset)));
156 }
157 fseek(fin, cur, SEEK_SET);
158 return t;
159}
diff --git a/noncore/apps/opie-reader/ztxt.h b/noncore/apps/opie-reader/ztxt.h
new file mode 100644
index 0000000..b8ad29c
--- a/dev/null
+++ b/noncore/apps/opie-reader/ztxt.h
@@ -0,0 +1,102 @@
1#ifndef __ztxt_h
2#define __ztxt_h
3
4#include "CExpander.h"
5#include <zlib.h>
6#include "pdb.h"
7/*
8 * Stuff common to both Weasel Reader and makeztxt
9 *
10 * $Id$
11 *
12 */
13
14#ifndef _WEASEL_COMMON_H_
15#define _WEASEL_COMMON_H_ 1
16
17
18/* Padding is no good */
19#if defined(__GNUC__) && defined(__UNIX__)
20# pragma pack(2)
21#endif
22
23/* The default creator is Weasel Reader 'GPlm' */
24#define GPLM_CREATOR_ID "GPlm"
25/* Databases of type 'zTXT' */
26#define ZTXT_TYPE_ID "zTXT"
27/* Size of one database record */
28#define RECORD_SIZE 8192
29/* Allow largest WBIT size for data. Lower with command line options
30 in makeztxt */
31#define MAXWBITS 15
32/* Max length for a bookmark/annotation title */
33#define MAX_BMRK_LENGTH 20
34
35
36/*****************************************************
37 * This is the zTXT document header (record #0) *
38 * ----zTXT version 1.42---- *
39 *****************************************************/
40typedef struct zTXT_record0Type {
41 UInt16 version; /* zTXT format version */
42 UInt16 numRecords; /* Number of data (TEXT) records */
43 UInt32 size; /* Size in bytes of uncomp. data */
44 UInt16 recordSize; /* Size of a single data record */
45 UInt16 numBookmarks; /* Number of bookmarks in DB */
46 UInt16 bookmarkRecord; /* Record containing bookmarks */
47 UInt16 numAnnotations; /* Number of annotation records */
48 UInt16 annotationRecord; /* Record # of annotation index */
49 UInt8 randomAccess; /* 1 if compressed w/Z_FULL_FLUSH */
50 UInt8 padding[0x20 - 19]; /* Pad to a size of 0x20 bytes */
51} zTXT_record0;
52
53struct zTXTbkmk
54{
55 UInt32 offset;
56 tchar title[MAX_BMRK_LENGTH];
57};
58
59#endif
60
61
62const UInt32 ZTXT_ID = 0x5458547a;
63
64class ztxt : public CExpander, Cpdb
65{
66 bool bInit;
67 UInt32 buffersize;
68 UInt32 buffercontent;
69 UInt8* expandedtextbuffer;
70 UInt8* compressedtextbuffer;
71 z_stream zstream;
72 size_t bufferpos;
73 UInt16 bufferrec;
74 zTXT_record0 hdr0;
75 size_t currentpos;
76 void home();
77 public:
78 virtual void sizes(unsigned long& _file, unsigned long& _text)
79 {
80 _file = file_length;
81 _text = ntohl(hdr0.size);
82 }
83 virtual bool hasrandomaccess() { return (hdr0.randomAccess != 0); }
84 virtual ~ztxt()
85 {
86 if (expandedtextbuffer != NULL) delete [] expandedtextbuffer;
87 if (compressedtextbuffer != NULL) delete [] compressedtextbuffer;
88 if (bInit)
89 {
90 inflateEnd(&zstream);
91 }
92 }
93 ztxt();
94 virtual int openfile(const char *src);
95 virtual int getch();
96 virtual unsigned int locate();
97 virtual void locate(unsigned int n);
98 virtual CList<Bkmk>* getbkmklist();
99};
100
101#endif
102