author | pohly <pohly> | 2004-08-24 20:52:45 (UTC) |
---|---|---|
committer | pohly <pohly> | 2004-08-24 20:52:45 (UTC) |
commit | 73253e93327cf4ef0932de1b4afb56af22a0f37e (patch) (unidiff) | |
tree | 1c9a7a6dd3341e036a894d348a3372525d29acec /noncore/apps/opie-reader/CHM.cpp | |
parent | e90847c784c48bd21bf8768cb38edb853b832697 (diff) | |
download | opie-73253e93327cf4ef0932de1b4afb56af22a0f37e.zip opie-73253e93327cf4ef0932de1b4afb56af22a0f37e.tar.gz opie-73253e93327cf4ef0932de1b4afb56af22a0f37e.tar.bz2 |
updated source to opie-reader 0.7g
Diffstat (limited to 'noncore/apps/opie-reader/CHM.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/CHM.cpp | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/CHM.cpp b/noncore/apps/opie-reader/CHM.cpp new file mode 100644 index 0000000..9d1eb87 --- a/dev/null +++ b/noncore/apps/opie-reader/CHM.cpp | |||
@@ -0,0 +1,380 @@ | |||
1 | #include "CHM.h" | ||
2 | #include "chm_lib.h" | ||
3 | #include "static.h" | ||
4 | #include <qstring.h> | ||
5 | #include <qstringlist.h> | ||
6 | #include <stdio.h> | ||
7 | #include <qimage.h> | ||
8 | #include <qpixmap.h> | ||
9 | |||
10 | #ifndef __STATIC | ||
11 | extern "C" | ||
12 | { | ||
13 | CExpander* newcodec() { return new CHM; } | ||
14 | } | ||
15 | #endif | ||
16 | |||
17 | static int _print_ui_index(struct chmFile *h, struct chmUnitInfo *ui, | ||
18 | void *context) | ||
19 | { | ||
20 | CHM *chm = (CHM *)context; | ||
21 | QString temp = "<tr>"; | ||
22 | char buff[1024]; | ||
23 | sprintf( buff,"<td align=right>%8d\n</td><td><a href=\"%s\">%s</a></td></tr>",(int)ui->length, ui->path, ui->path); | ||
24 | temp += buff; | ||
25 | chm->addContent(temp); | ||
26 | return CHM_ENUMERATOR_CONTINUE; | ||
27 | } | ||
28 | |||
29 | static int _get_hhc (struct chmFile *h, struct chmUnitInfo *ui, | ||
30 | void *context) | ||
31 | { | ||
32 | CHM *chm = (CHM *)context; | ||
33 | QString PathName = ui->path; | ||
34 | if (PathName.find(".hhc") > -1) { | ||
35 | chm->setPath(PathName); | ||
36 | } | ||
37 | return CHM_ENUMERATOR_CONTINUE; | ||
38 | } | ||
39 | |||
40 | CHM::CHM() { | ||
41 | chmFile = NULL; | ||
42 | chmPath = ""; | ||
43 | chmHHCPath = ""; | ||
44 | chmBuffer = ""; | ||
45 | bufpos = 0; | ||
46 | } | ||
47 | |||
48 | CHM::~CHM() { | ||
49 | if (chmFile != NULL) | ||
50 | chm_close(chmFile); | ||
51 | } | ||
52 | |||
53 | void CHM::suspend() { | ||
54 | #ifdef USEQPE | ||
55 | bSuspended = true; | ||
56 | //suspos = gztell(file); | ||
57 | chm_close(chmFile); | ||
58 | chmFile = NULL; | ||
59 | sustime = time(NULL); | ||
60 | #endif | ||
61 | } | ||
62 | |||
63 | void CHM::unsuspend() { | ||
64 | #ifdef USEQPE | ||
65 | if (bSuspended) | ||
66 | { | ||
67 | bSuspended = false; | ||
68 | int delay = time(NULL) - sustime; | ||
69 | if (delay < 10) | ||
70 | sleep(10-delay); | ||
71 | chmFile = chm_open(fname); | ||
72 | for (int i = 0; chmFile == NULL && i < 5; i++) { | ||
73 | sleep(5); | ||
74 | chmFile = chm_open(fname); | ||
75 | } | ||
76 | if (chmFile == NULL) { | ||
77 | QMessageBox::warning(NULL, PROGNAME, "Couldn't reopen file"); | ||
78 | exit(0); | ||
79 | } | ||
80 | //suspos = gzseek(file, suspos, SEEK_SET); | ||
81 | } | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | void CHM::addContent(QString content) { | ||
86 | chmBuffer += content; | ||
87 | } | ||
88 | |||
89 | void CHM::FillHomeContent() { | ||
90 | if (chmHHCPath != "") { | ||
91 | const char *ext; | ||
92 | char buffer[65536]; | ||
93 | unsigned int swath, offset; | ||
94 | QString tmp=""; | ||
95 | QString HTML=""; | ||
96 | /* try to find the file */ | ||
97 | const char *filename = (const char *)chmHHCPath; | ||
98 | if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS) | ||
99 | { | ||
100 | chmBuffer = "HELP"; | ||
101 | fsize = chmBuffer.length(); | ||
102 | return; | ||
103 | } | ||
104 | m_homestart = m_ui.start; | ||
105 | m_homeend = m_homestart + m_ui.length; | ||
106 | swath = 65536; | ||
107 | offset = 0; | ||
108 | fsize = m_ui.length; | ||
109 | while (offset < m_ui.length) | ||
110 | { | ||
111 | if ((m_ui.length - offset) < 65536) | ||
112 | swath = m_ui.length - offset; | ||
113 | else | ||
114 | swath = 65536; | ||
115 | swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath); | ||
116 | tmp += buffer; | ||
117 | offset += swath; | ||
118 | } | ||
119 | HTML +="<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN>\r\n"; | ||
120 | HTML +="<HTML>\r\n"; | ||
121 | HTML +="<BODY>\r\n"; | ||
122 | HTML +="<h2>Home Page</h2>\r\n"; | ||
123 | HTML +="<h3>\r\n"; | ||
124 | QStringList qsl = QStringList::split("\r\n",tmp); | ||
125 | QString NameFind ="<param name=\"Name\" value=\""; | ||
126 | QString LocalFind = "<param name=\"Local\" value=\""; | ||
127 | QString ULOpenFind = "<UL>"; | ||
128 | QString LIOpenFind = "<LI>"; | ||
129 | QString ULCloseFind = "</UL>"; | ||
130 | QString Name = ""; | ||
131 | QString Local = ""; | ||
132 | for ( QStringList::Iterator it = qsl.begin(); it != qsl.end(); ++it ) { | ||
133 | QString Line = (*it); | ||
134 | int NamePos = Line.find( NameFind); | ||
135 | int LocalPos = Line.find( LocalFind); | ||
136 | if (NamePos > -1) { | ||
137 | Name = Line.mid(NamePos+NameFind.length(),Line.length()); | ||
138 | Name = Name.left(Name.length() - 2); | ||
139 | } | ||
140 | if (LocalPos > -1) { | ||
141 | Local = Line.mid(LocalPos+LocalFind.length(),Line.length()); | ||
142 | Local = Local.left(Local.length() - 2); | ||
143 | if (Name != "") { | ||
144 | HTML += "<br>\r\n<a href="; | ||
145 | HTML += Local; | ||
146 | HTML += ">"; | ||
147 | HTML += Name; | ||
148 | HTML += "</a>\r\n"; | ||
149 | Name = ""; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | HTML +="</h3>"; | ||
154 | HTML +="</BODY>\r\n"; | ||
155 | HTML +="</HTML>\r\n"; | ||
156 | chmHomeBuffer = HTML; | ||
157 | chmBuffer = HTML; | ||
158 | fsize = chmBuffer.length(); | ||
159 | m_currentstart = m_ui.start; | ||
160 | m_currentend = m_currentstart+chmBuffer.length(); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | bool CHM::FillBuffer() | ||
165 | { | ||
166 | bool bRetVal = false; | ||
167 | char buffer[65536]; | ||
168 | int swath, offset; | ||
169 | chmBuffer = ""; | ||
170 | swath = 65536; | ||
171 | offset = 0; | ||
172 | fsize = m_ui.length; | ||
173 | while (offset < m_ui.length) | ||
174 | { | ||
175 | if ((m_ui.length - offset) < 65536) | ||
176 | swath = m_ui.length - offset; | ||
177 | else | ||
178 | swath = 65536; | ||
179 | swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath); | ||
180 | chmBuffer += buffer; | ||
181 | offset += swath; | ||
182 | } | ||
183 | //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it | ||
184 | QString temp = chmBuffer.lower(); | ||
185 | int lpos = temp.find("</html"); | ||
186 | if (lpos > -1) { | ||
187 | chmBuffer.truncate(lpos); | ||
188 | chmBuffer = chmBuffer+"</HTML>"; | ||
189 | } | ||
190 | fsize = chmBuffer.length(); | ||
191 | |||
192 | bufpos = 0; | ||
193 | bRetVal = true; | ||
194 | m_currentstart = m_ui.start; | ||
195 | m_currentend = m_currentstart+chmBuffer.length(); | ||
196 | return bRetVal; | ||
197 | } | ||
198 | |||
199 | bool CHM::FillContent() { | ||
200 | bool bRetVal = false; | ||
201 | if (chmPath != "") { | ||
202 | /* try to find the file */ | ||
203 | const char *filename = (const char *)chmPath; | ||
204 | if (chm_resolve_object(chmFile, filename, &m_ui) != CHM_RESOLVE_SUCCESS) | ||
205 | { | ||
206 | fsize = chmBuffer.length(); | ||
207 | return bRetVal; | ||
208 | } | ||
209 | |||
210 | char buffer[65536]; | ||
211 | int swath, offset; | ||
212 | chmBuffer = ""; | ||
213 | swath = 65536; | ||
214 | offset = 0; | ||
215 | fsize = m_ui.length; | ||
216 | while (offset < m_ui.length) | ||
217 | { | ||
218 | if ((m_ui.length - offset) < 65536) | ||
219 | swath = m_ui.length - offset; | ||
220 | else | ||
221 | swath = 65536; | ||
222 | swath = (int)chm_retrieve_object(chmFile, &m_ui, (unsigned char *) buffer, offset, swath); | ||
223 | chmBuffer += buffer; | ||
224 | offset += swath; | ||
225 | } | ||
226 | //There seems to be a ton of gobbledygook at the end that is reminiscent of the hhc file - remove it | ||
227 | QString temp = chmBuffer.lower(); | ||
228 | int lpos = temp.find("</html"); | ||
229 | if (lpos > -1) { | ||
230 | chmBuffer.truncate(lpos); | ||
231 | chmBuffer = chmBuffer+"</HTML>"; | ||
232 | } | ||
233 | fsize = chmBuffer.length(); | ||
234 | |||
235 | bufpos = 0; | ||
236 | m_currentstart = m_ui.start; | ||
237 | m_currentend = m_currentstart+chmBuffer.length(); | ||
238 | bRetVal = true; | ||
239 | } | ||
240 | return bRetVal; | ||
241 | } | ||
242 | |||
243 | bool CHM::getFile(const QString& href) { | ||
244 | qDebug("Got:%s", (const char*)href); | ||
245 | bool bRetVal = false; | ||
246 | QString temp = chmPath; | ||
247 | chmPath = href; | ||
248 | if (FillContent()) { | ||
249 | qDebug("Got it"); | ||
250 | bRetVal = true; | ||
251 | } else { | ||
252 | qDebug("Missed"); | ||
253 | chmPath = temp; | ||
254 | FillContent(); | ||
255 | } | ||
256 | return bRetVal; | ||
257 | } | ||
258 | |||
259 | QImage *CHM::getPicture(const QString& href) { | ||
260 | QImage *img = NULL; | ||
261 | QString PicRef = "/"+href; | ||
262 | struct chmUnitInfo ui; | ||
263 | const char *ext; | ||
264 | /* try to find the file */ | ||
265 | const char *filename = (const char *)PicRef; | ||
266 | if (chm_resolve_object(chmFile, filename, &ui) != CHM_RESOLVE_SUCCESS) | ||
267 | { | ||
268 | qDebug ("Could not resolve image"); | ||
269 | return img; | ||
270 | } | ||
271 | if (ui.length > 0) { | ||
272 | char *temp = new char[ui.length]; | ||
273 | char buffer[65536]; | ||
274 | int swath, offset; | ||
275 | swath = 65536; | ||
276 | offset = 0; | ||
277 | |||
278 | while (offset < ui.length) | ||
279 | { | ||
280 | if ((ui.length - offset) < 65536) | ||
281 | swath = ui.length - offset; | ||
282 | else | ||
283 | swath = 65536; | ||
284 | swath = (int)chm_retrieve_object(chmFile, &ui, (unsigned char *) buffer, offset, swath); | ||
285 | memcpy( (void *) (temp + offset), (void *)&buffer, swath ); | ||
286 | offset += swath; | ||
287 | } | ||
288 | QByteArray qba; | ||
289 | qba.setRawData( (const char *)temp, ui.length); | ||
290 | QPixmap qpm(qba); | ||
291 | img = new QImage(qpm.convertToImage()); | ||
292 | qba.resetRawData((const char *)temp, ui.length); | ||
293 | delete[] temp; | ||
294 | } | ||
295 | |||
296 | return img; | ||
297 | } | ||
298 | |||
299 | int CHM::OpenFile(const char *src) { | ||
300 | if (chmFile != NULL) chm_close(chmFile); | ||
301 | struct stat _stat; | ||
302 | stat(src,&_stat); | ||
303 | fsize = _stat.st_size; | ||
304 | chmFile = chm_open(src); | ||
305 | if (chmFile != NULL) { | ||
306 | chm_enumerate(chmFile, | ||
307 | CHM_ENUMERATE_ALL, | ||
308 | _get_hhc, | ||
309 | (void *)this); | ||
310 | if ( chmPath != "") { | ||
311 | setHomePath(chmPath); | ||
312 | FillHomeContent(); | ||
313 | } | ||
314 | } | ||
315 | m_homepos = locate(); | ||
316 | qDebug("Home:%u", m_homepos); | ||
317 | return (chmFile==NULL); | ||
318 | } | ||
319 | |||
320 | int CHM::getch() { | ||
321 | if ( (bufpos+1) >= chmBuffer.length() ) | ||
322 | return EOF; | ||
323 | #ifdef _WINDOWS | ||
324 | QChar letter = chmBuffer.at(bufpos++); | ||
325 | #else | ||
326 | QChar letter = chmBuffer[bufpos++]; | ||
327 | #endif | ||
328 | return (int)(char)letter; | ||
329 | } | ||
330 | |||
331 | void CHM::getch(tchar& ch, CStyle& sty) | ||
332 | { | ||
333 | int ich = getch(); | ||
334 | ch = (ich == EOF) ? UEOF : ich; | ||
335 | } | ||
336 | |||
337 | void CHM::start2endSection() | ||
338 | { | ||
339 | m_currentstart = m_ui.start; | ||
340 | m_currentend = m_currentstart+chmBuffer.length(); | ||
341 | } | ||
342 | |||
343 | unsigned int CHM::locate() { | ||
344 | return m_currentstart+bufpos; | ||
345 | } | ||
346 | |||
347 | void CHM::locate(unsigned int n) { | ||
348 | if (n == 0) n = m_homepos; | ||
349 | if (n >= m_homestart && n < m_homeend) | ||
350 | { | ||
351 | FillHomeContent(); | ||
352 | bufpos = n - m_homestart; | ||
353 | start2endSection(); | ||
354 | qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend); | ||
355 | } | ||
356 | else if (n >= m_currentstart && n < m_currentend) | ||
357 | { | ||
358 | bufpos = n - m_currentstart; | ||
359 | } | ||
360 | else if (CHM_RESOLVE_FAILURE == chm_resolve_location(chmFile, n/4, &m_ui)) | ||
361 | { | ||
362 | qDebug("Resolve failure"); | ||
363 | FillHomeContent(); | ||
364 | bufpos = 0; | ||
365 | start2endSection(); | ||
366 | qDebug("Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend); | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | qDebug("Resolve success"); | ||
371 | FillBuffer(); | ||
372 | start2endSection(); | ||
373 | bufpos=n-m_currentstart; | ||
374 | qDebug("Not Home:%u:<%u, %u, %u>", m_ui.start, m_currentstart, n, m_currentend); | ||
375 | } | ||
376 | } | ||
377 | |||
378 | void CHM::sizes(unsigned long& _file, unsigned long& _text) { | ||
379 | _text = _file = fsize; | ||
380 | } | ||