summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3.c2
-rw-r--r--libopie2/opieui/oimageeffect.cpp5
-rw-r--r--library/global.cpp30
-rw-r--r--noncore/apps/opie-reader/Bkmks.cpp1
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp4
-rw-r--r--noncore/apps/zsafe/zsafe.cpp57
-rw-r--r--noncore/comm/keypebble/vncauth.c6
-rw-r--r--noncore/net/ftplib/ftplib.c4
-rw-r--r--noncore/todayplugins/stockticker/libstocks/csv.c140
-rw-r--r--noncore/todayplugins/stockticker/libstocks/currency.c1
-rw-r--r--noncore/todayplugins/stockticker/libstocks/lists.h1
-rw-r--r--noncore/todayplugins/stockticker/libstocks/stocks.c189
-rw-r--r--rsync/delta.c2
13 files changed, 270 insertions, 172 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c
index acaecf7..c8cd3e2 100644
--- a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c
@@ -1,672 +1,672 @@
1#include "libmpeg3.h" 1#include "libmpeg3.h"
2#include "mpeg3protos.h" 2#include "mpeg3protos.h"
3 3
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6 6
7#define MAX(a, b) ((a) > (b) ? (a) : (b)) 7#define MAX(a, b) ((a) > (b) ? (a) : (b))
8 8
9mpeg3_t* mpeg3_new(char *path) 9mpeg3_t* mpeg3_new(char *path)
10{ 10{
11 int i; 11 int i;
12 mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t)); 12 mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t));
13 file->cpus = 1; 13 file->cpus = 1;
14 file->fs = mpeg3_new_fs(path); 14 file->fs = mpeg3_new_fs(path);
15 file->have_mmx = mpeg3_mmx_test(); 15 file->have_mmx = mpeg3_mmx_test();
16 file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); 16 file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
17 return file; 17 return file;
18} 18}
19 19
20int mpeg3_delete(mpeg3_t *file) 20int mpeg3_delete(mpeg3_t *file)
21{ 21{
22 int i; 22 int i;
23 23
24 for(i = 0; i < file->total_vstreams; i++) 24 for(i = 0; i < file->total_vstreams; i++)
25 mpeg3_delete_vtrack(file, file->vtrack[i]); 25 mpeg3_delete_vtrack(file, file->vtrack[i]);
26 26
27 for(i = 0; i < file->total_astreams; i++) 27 for(i = 0; i < file->total_astreams; i++)
28 mpeg3_delete_atrack(file, file->atrack[i]); 28 mpeg3_delete_atrack(file, file->atrack[i]);
29 29
30 mpeg3_delete_fs(file->fs); 30 mpeg3_delete_fs(file->fs);
31 mpeg3_delete_demuxer(file->demuxer); 31 mpeg3_delete_demuxer(file->demuxer);
32 free(file); 32 free(file);
33} 33}
34 34
35int mpeg3_check_sig(char *path) 35int mpeg3_check_sig(char *path)
36{ 36{
37 mpeg3_fs_t *fs; 37 mpeg3_fs_t *fs;
38 unsigned int bits; 38 unsigned int bits;
39 char *ext; 39 char *ext;
40 int result = 0; 40 int result = 0;
41 41
42 fs = mpeg3_new_fs(path); 42 fs = mpeg3_new_fs(path);
43 if(mpeg3io_open_file(fs)) 43 if(mpeg3io_open_file(fs))
44 { 44 {
45/* File not found */ 45/* File not found */
46 return 0; 46 return mpeg3_delete_fs(fs);
47 } 47 }
48 48
49 bits = mpeg3io_read_int32(fs); 49 bits = mpeg3io_read_int32(fs);
50/* Test header */ 50/* Test header */
51 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) 51 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER)
52 { 52 {
53 result = 1; 53 result = 1;
54 } 54 }
55 else 55 else
56 if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || 56 if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
57 (bits == MPEG3_PACK_START_CODE) || 57 (bits == MPEG3_PACK_START_CODE) ||
58 ((bits & 0xfff00000) == 0xfff00000) || 58 ((bits & 0xfff00000) == 0xfff00000) ||
59 (bits == MPEG3_SEQUENCE_START_CODE) || 59 (bits == MPEG3_SEQUENCE_START_CODE) ||
60 (bits == MPEG3_PICTURE_START_CODE) || 60 (bits == MPEG3_PICTURE_START_CODE) ||
61 (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || 61 (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
62 ((bits >> 8) == MPEG3_ID3_PREFIX) || 62 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
63 (bits == MPEG3_RIFF_CODE)) 63 (bits == MPEG3_RIFF_CODE))
64 { 64 {
65 result = 1; 65 result = 1;
66 66
67 ext = strrchr(path, '.'); 67 ext = strrchr(path, '.');
68 if(ext) 68 if(ext)
69 { 69 {
70/* Test file extension. */ 70/* Test file extension. */
71 if(strncasecmp(ext, ".mp2", 4) && 71 if(strncasecmp(ext, ".mp2", 4) &&
72 // strncasecmp(ext, ".mp3", 4) && 72 // strncasecmp(ext, ".mp3", 4) &&
73 strncasecmp(ext, ".m1v", 4) && 73 strncasecmp(ext, ".m1v", 4) &&
74 strncasecmp(ext, ".m2v", 4) && 74 strncasecmp(ext, ".m2v", 4) &&
75 strncasecmp(ext, ".m2s", 4) && 75 strncasecmp(ext, ".m2s", 4) &&
76 strncasecmp(ext, ".mpg", 4) && 76 strncasecmp(ext, ".mpg", 4) &&
77 strncasecmp(ext, ".vob", 4) && 77 strncasecmp(ext, ".vob", 4) &&
78 strncasecmp(ext, ".mpeg", 4) && 78 strncasecmp(ext, ".mpeg", 4) &&
79 strncasecmp(ext, ".ac3", 4)) 79 strncasecmp(ext, ".ac3", 4))
80 result = 0; 80 result = 0;
81 } 81 }
82 } 82 }
83 83
84 mpeg3io_close_file(fs); 84 mpeg3io_close_file(fs);
85 mpeg3_delete_fs(fs); 85 mpeg3_delete_fs(fs);
86 return result; 86 return result;
87} 87}
88 88
89mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) 89mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file)
90{ 90{
91 mpeg3_t *file = 0; 91 mpeg3_t *file = 0;
92 unsigned int bits; 92 unsigned int bits;
93 int i, done; 93 int i, done;
94 94
95/* Initialize the file structure */ 95/* Initialize the file structure */
96 file = mpeg3_new(path); 96 file = mpeg3_new(path);
97 97
98/* Need to perform authentication before reading a single byte. */ 98/* Need to perform authentication before reading a single byte. */
99 if(mpeg3io_open_file(file->fs)) 99 if(mpeg3io_open_file(file->fs))
100 { 100 {
101 mpeg3_delete(file); 101 mpeg3_delete(file);
102 return 0; 102 return 0;
103 } 103 }
104 104
105/* =============================== Create the title objects ========================= */ 105/* =============================== Create the title objects ========================= */
106 bits = mpeg3io_read_int32(file->fs); 106 bits = mpeg3io_read_int32(file->fs);
107 107
108 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */ 108 if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */
109 { 109 {
110/* Table of contents for another file */ 110/* Table of contents for another file */
111 if(mpeg3_read_toc(file)) 111 if(mpeg3_read_toc(file))
112 { 112 {
113 mpeg3_delete(file); 113 mpeg3_delete(file);
114 return 0; 114 return 0;
115 } 115 }
116 mpeg3io_close_file(file->fs); 116 mpeg3io_close_file(file->fs);
117 } 117 }
118 else 118 else
119 if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) 119 if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
120 { 120 {
121/* Transport stream */ 121/* Transport stream */
122 file->packet_size = MPEG3_TS_PACKET_SIZE; 122 file->packet_size = MPEG3_TS_PACKET_SIZE;
123 file->is_transport_stream = 1; 123 file->is_transport_stream = 1;
124 } 124 }
125 else 125 else
126 if(bits == MPEG3_PACK_START_CODE) 126 if(bits == MPEG3_PACK_START_CODE)
127 { 127 {
128/* Program stream */ 128/* Program stream */
129 file->packet_size = MPEG3_DVD_PACKET_SIZE; 129 file->packet_size = MPEG3_DVD_PACKET_SIZE;
130 file->is_program_stream = 1; 130 file->is_program_stream = 1;
131 } 131 }
132 else 132 else
133 if((bits & 0xfff00000) == 0xfff00000 || 133 if((bits & 0xfff00000) == 0xfff00000 ||
134 ((bits >> 8) == MPEG3_ID3_PREFIX) || 134 ((bits >> 8) == MPEG3_ID3_PREFIX) ||
135 (bits == MPEG3_RIFF_CODE)) 135 (bits == MPEG3_RIFF_CODE))
136 { 136 {
137/* MPEG Audio only */ 137/* MPEG Audio only */
138 file->packet_size = MPEG3_DVD_PACKET_SIZE; 138 file->packet_size = MPEG3_DVD_PACKET_SIZE;
139 file->has_audio = 1; 139 file->has_audio = 1;
140 file->is_audio_stream = 1; 140 file->is_audio_stream = 1;
141 } 141 }
142 else 142 else
143 if(bits == MPEG3_SEQUENCE_START_CODE || 143 if(bits == MPEG3_SEQUENCE_START_CODE ||
144 bits == MPEG3_PICTURE_START_CODE) 144 bits == MPEG3_PICTURE_START_CODE)
145 { 145 {
146/* Video only */ 146/* Video only */
147 file->packet_size = MPEG3_DVD_PACKET_SIZE; 147 file->packet_size = MPEG3_DVD_PACKET_SIZE;
148 file->is_video_stream = 1; 148 file->is_video_stream = 1;
149 } 149 }
150 else 150 else
151 if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) 151 if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
152 { 152 {
153/* AC3 Audio only */ 153/* AC3 Audio only */
154 file->packet_size = MPEG3_DVD_PACKET_SIZE; 154 file->packet_size = MPEG3_DVD_PACKET_SIZE;
155 file->has_audio = 1; 155 file->has_audio = 1;
156 file->is_audio_stream = 1; 156 file->is_audio_stream = 1;
157 } 157 }
158 else 158 else
159 { 159 {
160/* file->packet_size = MPEG3_DVD_PACKET_SIZE; */ 160/* file->packet_size = MPEG3_DVD_PACKET_SIZE; */
161/* file->is_audio_stream = 1; */ 161/* file->is_audio_stream = 1; */
162 mpeg3_delete(file); 162 mpeg3_delete(file);
163 fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n"); 163 fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n");
164 return 0; 164 return 0;
165 } 165 }
166 166
167/* Create title */ 167/* Create title */
168/* Copy timecodes from an old demuxer */ 168/* Copy timecodes from an old demuxer */
169 if(old_file && mpeg3_get_demuxer(old_file)) 169 if(old_file && mpeg3_get_demuxer(old_file))
170 { 170 {
171 mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file)); 171 mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
172 } 172 }
173 else 173 else
174/* Start from scratch */ 174/* Start from scratch */
175 if(!file->demuxer->total_titles) 175 if(!file->demuxer->total_titles)
176 { 176 {
177 mpeg3demux_create_title(file->demuxer, 0, 0); 177 mpeg3demux_create_title(file->demuxer, 0, 0);
178 } 178 }
179 179
180/* =============================== Get title information ========================= */ 180/* =============================== Get title information ========================= */
181 if(file->is_transport_stream || file->is_program_stream) 181 if(file->is_transport_stream || file->is_program_stream)
182 { 182 {
183/* Create video tracks */ 183/* Create video tracks */
184/* Video must be created before audio because audio uses the video timecode */ 184/* Video must be created before audio because audio uses the video timecode */
185/* to get its length. */ 185/* to get its length. */
186 for(i = 0; i < MPEG3_MAX_STREAMS; i++) 186 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
187 { 187 {
188 if(file->demuxer->vstream_table[i]) 188 if(file->demuxer->vstream_table[i])
189 { 189 {
190 file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer); 190 file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer);
191 if(file->vtrack[file->total_vstreams]) file->total_vstreams++; 191 if(file->vtrack[file->total_vstreams]) file->total_vstreams++;
192 } 192 }
193 } 193 }
194 194
195/* Create audio tracks */ 195/* Create audio tracks */
196 for(i = 0; i < MPEG3_MAX_STREAMS; i++) 196 for(i = 0; i < MPEG3_MAX_STREAMS; i++)
197 { 197 {
198 if(file->demuxer->astream_table[i]) 198 if(file->demuxer->astream_table[i])
199 { 199 {
200 file->atrack[file->total_astreams] = mpeg3_new_atrack(file, 200 file->atrack[file->total_astreams] = mpeg3_new_atrack(file,
201 i, 201 i,
202 file->demuxer->astream_table[i], 202 file->demuxer->astream_table[i],
203 file->demuxer); 203 file->demuxer);
204 if(file->atrack[file->total_astreams]) file->total_astreams++; 204 if(file->atrack[file->total_astreams]) file->total_astreams++;
205 } 205 }
206 } 206 }
207 } 207 }
208 else 208 else
209 if(file->is_video_stream) 209 if(file->is_video_stream)
210 { 210 {
211/* Create video tracks */ 211/* Create video tracks */
212 file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer); 212 file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer);
213 if(file->vtrack[0]) file->total_vstreams++; 213 if(file->vtrack[0]) file->total_vstreams++;
214 } 214 }
215 else 215 else
216 if(file->is_audio_stream) 216 if(file->is_audio_stream)
217 { 217 {
218/* Create audio tracks */ 218/* Create audio tracks */
219 file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer); 219 file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer);
220 if(file->atrack[0]) file->total_astreams++; 220 if(file->atrack[0]) file->total_astreams++;
221 } 221 }
222 222
223 if(file->total_vstreams) file->has_video = 1; 223 if(file->total_vstreams) file->has_video = 1;
224 if(file->total_astreams) file->has_audio = 1; 224 if(file->total_astreams) file->has_audio = 1;
225 225
226 mpeg3io_close_file(file->fs); 226 mpeg3io_close_file(file->fs);
227 return file; 227 return file;
228} 228}
229 229
230mpeg3_t* mpeg3_open(char *path) 230mpeg3_t* mpeg3_open(char *path)
231{ 231{
232 return mpeg3_open_copy(path, 0); 232 return mpeg3_open_copy(path, 0);
233} 233}
234 234
235int mpeg3_close(mpeg3_t *file) 235int mpeg3_close(mpeg3_t *file)
236{ 236{
237/* File is closed in the same procedure it is opened in. */ 237/* File is closed in the same procedure it is opened in. */
238 mpeg3_delete(file); 238 mpeg3_delete(file);
239 return 0; 239 return 0;
240} 240}
241 241
242int mpeg3_set_cpus(mpeg3_t *file, int cpus) 242int mpeg3_set_cpus(mpeg3_t *file, int cpus)
243{ 243{
244 int i; 244 int i;
245 file->cpus = cpus; 245 file->cpus = cpus;
246 for(i = 0; i < file->total_vstreams; i++) 246 for(i = 0; i < file->total_vstreams; i++)
247 mpeg3video_set_cpus(file->vtrack[i]->video, cpus); 247 mpeg3video_set_cpus(file->vtrack[i]->video, cpus);
248 return 0; 248 return 0;
249} 249}
250 250
251int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) 251int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)
252{ 252{
253 int i; 253 int i;
254 file->have_mmx = use_mmx; 254 file->have_mmx = use_mmx;
255 for(i = 0; i < file->total_vstreams; i++) 255 for(i = 0; i < file->total_vstreams; i++)
256 mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx); 256 mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx);
257 return 0; 257 return 0;
258} 258}
259 259
260int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) 260int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams)
261{ 261{
262 mpeg3_t *file = mpeg3_open(path); 262 mpeg3_t *file = mpeg3_open(path);
263 mpeg3_demuxer_t *demuxer; 263 mpeg3_demuxer_t *demuxer;
264 int i; 264 int i;
265 265
266 if(file) 266 if(file)
267 { 267 {
268 fprintf(output, "TOCVERSION 2\n" 268 fprintf(output, "TOCVERSION 2\n"
269 "PATH: %s\n", path); 269 "PATH: %s\n", path);
270 demuxer = mpeg3_new_demuxer(file, 0, 0, -1); 270 demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
271 mpeg3demux_create_title(demuxer, timecode_search, output); 271 mpeg3demux_create_title(demuxer, timecode_search, output);
272/* Just print the first title's streams */ 272/* Just print the first title's streams */
273 if(print_streams) mpeg3demux_print_streams(demuxer, output); 273 if(print_streams) mpeg3demux_print_streams(demuxer, output);
274 274
275 fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes); 275 fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes);
276 fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size); 276 fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size);
277 277
278 mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output); 278 mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output);
279 279
280 mpeg3_delete_demuxer(demuxer); 280 mpeg3_delete_demuxer(demuxer);
281 mpeg3_close(file); 281 mpeg3_close(file);
282 return 0; 282 return 0;
283 } 283 }
284 return 1; 284 return 1;
285} 285}
286 286
287int mpeg3_read_toc(mpeg3_t *file) 287int mpeg3_read_toc(mpeg3_t *file)
288{ 288{
289 char string[MPEG3_STRLEN]; 289 char string[MPEG3_STRLEN];
290 int number1; 290 int number1;
291 291
292/* Test version number */ 292/* Test version number */
293 file->is_program_stream = 1; 293 file->is_program_stream = 1;
294 mpeg3io_seek(file->fs, 0); 294 mpeg3io_seek(file->fs, 0);
295 fscanf(file->fs->fd, "%s %d", string, &number1); 295 fscanf(file->fs->fd, "%s %d", string, &number1);
296 if(number1 > 2 || number1 < 2) return 1; 296 if(number1 > 2 || number1 < 2) return 1;
297 297
298/* Read titles */ 298/* Read titles */
299 mpeg3demux_read_titles(file->demuxer); 299 mpeg3demux_read_titles(file->demuxer);
300 return 0; 300 return 0;
301} 301}
302 302
303int mpeg3_has_audio(mpeg3_t *file) 303int mpeg3_has_audio(mpeg3_t *file)
304{ 304{
305 return file->has_audio; 305 return file->has_audio;
306} 306}
307 307
308int mpeg3_total_astreams(mpeg3_t *file) 308int mpeg3_total_astreams(mpeg3_t *file)
309{ 309{
310 return file->total_astreams; 310 return file->total_astreams;
311} 311}
312 312
313int mpeg3_audio_channels(mpeg3_t *file, 313int mpeg3_audio_channels(mpeg3_t *file,
314 int stream) 314 int stream)
315{ 315{
316 if(file->has_audio) 316 if(file->has_audio)
317 return file->atrack[stream]->channels; 317 return file->atrack[stream]->channels;
318 return -1; 318 return -1;
319} 319}
320 320
321int mpeg3_sample_rate(mpeg3_t *file, 321int mpeg3_sample_rate(mpeg3_t *file,
322 int stream) 322 int stream)
323{ 323{
324 if(file->has_audio) 324 if(file->has_audio)
325 return file->atrack[stream]->sample_rate; 325 return file->atrack[stream]->sample_rate;
326 return -1; 326 return -1;
327} 327}
328 328
329long mpeg3_get_sample(mpeg3_t *file, 329long mpeg3_get_sample(mpeg3_t *file,
330 int stream) 330 int stream)
331{ 331{
332 if(file->has_audio) 332 if(file->has_audio)
333 return file->atrack[stream]->current_position; 333 return file->atrack[stream]->current_position;
334 return -1; 334 return -1;
335} 335}
336 336
337int mpeg3_set_sample(mpeg3_t *file, 337int mpeg3_set_sample(mpeg3_t *file,
338 long sample, 338 long sample,
339 int stream) 339 int stream)
340{ 340{
341 if(file->has_audio) 341 if(file->has_audio)
342 { 342 {
343 file->atrack[stream]->current_position = sample; 343 file->atrack[stream]->current_position = sample;
344 mpeg3audio_seek_sample(file->atrack[stream]->audio, sample); 344 mpeg3audio_seek_sample(file->atrack[stream]->audio, sample);
345 return 0; 345 return 0;
346 } 346 }
347 return -1; 347 return -1;
348} 348}
349 349
350long mpeg3_audio_samples(mpeg3_t *file, 350long mpeg3_audio_samples(mpeg3_t *file,
351 int stream) 351 int stream)
352{ 352{
353 if(file->has_audio) 353 if(file->has_audio)
354 return file->atrack[stream]->total_samples; 354 return file->atrack[stream]->total_samples;
355 return -1; 355 return -1;
356} 356}
357 357
358int mpeg3_has_video(mpeg3_t *file) 358int mpeg3_has_video(mpeg3_t *file)
359{ 359{
360 return file->has_video; 360 return file->has_video;
361} 361}
362 362
363int mpeg3_total_vstreams(mpeg3_t *file) 363int mpeg3_total_vstreams(mpeg3_t *file)
364{ 364{
365 return file->total_vstreams; 365 return file->total_vstreams;
366} 366}
367 367
368int mpeg3_video_width(mpeg3_t *file, 368int mpeg3_video_width(mpeg3_t *file,
369 int stream) 369 int stream)
370{ 370{
371 if(file->has_video) 371 if(file->has_video)
372 return file->vtrack[stream]->width; 372 return file->vtrack[stream]->width;
373 return -1; 373 return -1;
374} 374}
375 375
376int mpeg3_video_height(mpeg3_t *file, 376int mpeg3_video_height(mpeg3_t *file,
377 int stream) 377 int stream)
378{ 378{
379 if(file->has_video) 379 if(file->has_video)
380 return file->vtrack[stream]->height; 380 return file->vtrack[stream]->height;
381 return -1; 381 return -1;
382} 382}
383 383
384float mpeg3_frame_rate(mpeg3_t *file, 384float mpeg3_frame_rate(mpeg3_t *file,
385 int stream) 385 int stream)
386{ 386{
387 if(file->has_video) 387 if(file->has_video)
388 return file->vtrack[stream]->frame_rate; 388 return file->vtrack[stream]->frame_rate;
389 return -1; 389 return -1;
390} 390}
391 391
392long mpeg3_video_frames(mpeg3_t *file, 392long mpeg3_video_frames(mpeg3_t *file,
393 int stream) 393 int stream)
394{ 394{
395 if(file->has_video) 395 if(file->has_video)
396 return file->vtrack[stream]->total_frames; 396 return file->vtrack[stream]->total_frames;
397 return -1; 397 return -1;
398} 398}
399 399
400long mpeg3_get_frame(mpeg3_t *file, 400long mpeg3_get_frame(mpeg3_t *file,
401 int stream) 401 int stream)
402{ 402{
403 if(file->has_video) 403 if(file->has_video)
404 return file->vtrack[stream]->current_position; 404 return file->vtrack[stream]->current_position;
405 return -1; 405 return -1;
406} 406}
407 407
408int mpeg3_set_frame(mpeg3_t *file, 408int mpeg3_set_frame(mpeg3_t *file,
409 long frame, 409 long frame,
410 int stream) 410 int stream)
411{ 411{
412 if(file->has_video) 412 if(file->has_video)
413 { 413 {
414 file->vtrack[stream]->current_position = frame; 414 file->vtrack[stream]->current_position = frame;
415 mpeg3video_seek_frame(file->vtrack[stream]->video, frame); 415 mpeg3video_seek_frame(file->vtrack[stream]->video, frame);
416 return 0; 416 return 0;
417 } 417 }
418 return -1; 418 return -1;
419} 419}
420 420
421int mpeg3_seek_percentage(mpeg3_t *file, double percentage) 421int mpeg3_seek_percentage(mpeg3_t *file, double percentage)
422{ 422{
423 int i; 423 int i;
424 for(i = 0; i < file->total_astreams; i++) 424 for(i = 0; i < file->total_astreams; i++)
425 { 425 {
426 mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage); 426 mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage);
427 } 427 }
428 428
429 for(i = 0; i < file->total_vstreams; i++) 429 for(i = 0; i < file->total_vstreams; i++)
430 { 430 {
431 mpeg3video_seek_percentage(file->vtrack[i]->video, percentage); 431 mpeg3video_seek_percentage(file->vtrack[i]->video, percentage);
432 } 432 }
433 return 0; 433 return 0;
434} 434}
435 435
436int mpeg3_previous_frame(mpeg3_t *file, int stream) 436int mpeg3_previous_frame(mpeg3_t *file, int stream)
437{ 437{
438 file->last_type_read = 2; 438 file->last_type_read = 2;
439 file->last_stream_read = stream; 439 file->last_stream_read = stream;
440 440
441 if(file->has_video) 441 if(file->has_video)
442 return mpeg3video_previous_frame(file->vtrack[stream]->video); 442 return mpeg3video_previous_frame(file->vtrack[stream]->video);
443} 443}
444 444
445double mpeg3_tell_percentage(mpeg3_t *file) 445double mpeg3_tell_percentage(mpeg3_t *file)
446{ 446{
447 double percent = 0; 447 double percent = 0;
448 if(file->last_type_read == 1) 448 if(file->last_type_read == 1)
449 { 449 {
450 percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer); 450 percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer);
451 } 451 }
452 452
453 if(file->last_type_read == 2) 453 if(file->last_type_read == 2)
454 { 454 {
455 percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer); 455 percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer);
456 } 456 }
457 return percent; 457 return percent;
458} 458}
459 459
460double mpeg3_get_time(mpeg3_t *file) 460double mpeg3_get_time(mpeg3_t *file)
461{ 461{
462 double atime = 0, vtime = 0; 462 double atime = 0, vtime = 0;
463 463
464 if(file->is_transport_stream || file->is_program_stream) 464 if(file->is_transport_stream || file->is_program_stream)
465 { 465 {
466/* Timecode only available in transport stream */ 466/* Timecode only available in transport stream */
467 if(file->last_type_read == 1) 467 if(file->last_type_read == 1)
468 { 468 {
469 atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer); 469 atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer);
470 } 470 }
471 else 471 else
472 if(file->last_type_read == 2) 472 if(file->last_type_read == 2)
473 { 473 {
474 vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer); 474 vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer);
475 } 475 }
476 } 476 }
477 else 477 else
478 { 478 {
479/* Use percentage and total time */ 479/* Use percentage and total time */
480 if(file->has_audio) 480 if(file->has_audio)
481 { 481 {
482 atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) * 482 atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) *
483 mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0); 483 mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0);
484 } 484 }
485 485
486 if(file->has_video) 486 if(file->has_video)
487 { 487 {
488 vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) * 488 vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) *
489 mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0); 489 mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0);
490 } 490 }
491 } 491 }
492 492
493 return MAX(atime, vtime); 493 return MAX(atime, vtime);
494} 494}
495 495
496int mpeg3_end_of_audio(mpeg3_t *file, int stream) 496int mpeg3_end_of_audio(mpeg3_t *file, int stream)
497{ 497{
498 int result = 0; 498 int result = 0;
499 result = mpeg3demux_eof(file->atrack[stream]->demuxer); 499 result = mpeg3demux_eof(file->atrack[stream]->demuxer);
500 return result; 500 return result;
501} 501}
502 502
503int mpeg3_end_of_video(mpeg3_t *file, int stream) 503int mpeg3_end_of_video(mpeg3_t *file, int stream)
504{ 504{
505 int result = 0; 505 int result = 0;
506 result = mpeg3demux_eof(file->vtrack[stream]->demuxer); 506 result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
507 return result; 507 return result;
508} 508}
509 509
510 510
511int mpeg3_read_frame(mpeg3_t *file, 511int mpeg3_read_frame(mpeg3_t *file,
512 unsigned char **output_rows, 512 unsigned char **output_rows,
513 int in_x, 513 int in_x,
514 int in_y, 514 int in_y,
515 int in_w, 515 int in_w,
516 int in_h, 516 int in_h,
517 int out_w, 517 int out_w,
518 int out_h, 518 int out_h,
519 int color_model, 519 int color_model,
520 int stream) 520 int stream)
521{ 521{
522 int result = -1; 522 int result = -1;
523 523
524 if(file->has_video) 524 if(file->has_video)
525 { 525 {
526 result = mpeg3video_read_frame(file->vtrack[stream]->video, 526 result = mpeg3video_read_frame(file->vtrack[stream]->video,
527 file->vtrack[stream]->current_position, 527 file->vtrack[stream]->current_position,
528 output_rows, 528 output_rows,
529 in_x, 529 in_x,
530 in_y, 530 in_y,
531 in_w, 531 in_w,
532 in_h, 532 in_h,
533 out_w, 533 out_w,
534 out_h, 534 out_h,
535 color_model); 535 color_model);
536 file->last_type_read = 2; 536 file->last_type_read = 2;
537 file->last_stream_read = stream; 537 file->last_stream_read = stream;
538 file->vtrack[stream]->current_position++; 538 file->vtrack[stream]->current_position++;
539 } 539 }
540 return result; 540 return result;
541} 541}
542 542
543int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream) 543int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)
544{ 544{
545 int result = -1; 545 int result = -1;
546 546
547 if(file->has_video) 547 if(file->has_video)
548 { 548 {
549 result = mpeg3video_drop_frames(file->vtrack[stream]->video, 549 result = mpeg3video_drop_frames(file->vtrack[stream]->video,
550 frames); 550 frames);
551 if(frames > 0) file->vtrack[stream]->current_position += frames; 551 if(frames > 0) file->vtrack[stream]->current_position += frames;
552 file->last_type_read = 2; 552 file->last_type_read = 2;
553 file->last_stream_read = stream; 553 file->last_stream_read = stream;
554 } 554 }
555 return result; 555 return result;
556} 556}
557 557
558int mpeg3_read_yuvframe(mpeg3_t *file, 558int mpeg3_read_yuvframe(mpeg3_t *file,
559 char *y_output, 559 char *y_output,
560 char *u_output, 560 char *u_output,
561 char *v_output, 561 char *v_output,
562 int in_x, 562 int in_x,
563 int in_y, 563 int in_y,
564 int in_w, 564 int in_w,
565 int in_h, 565 int in_h,
566 int stream) 566 int stream)
567{ 567{
568 int result = -1; 568 int result = -1;
569 569
570//printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer)); 570//printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
571 if(file->has_video) 571 if(file->has_video)
572 { 572 {
573 result = mpeg3video_read_yuvframe(file->vtrack[stream]->video, 573 result = mpeg3video_read_yuvframe(file->vtrack[stream]->video,
574 file->vtrack[stream]->current_position, 574 file->vtrack[stream]->current_position,
575 y_output, 575 y_output,
576 u_output, 576 u_output,
577 v_output, 577 v_output,
578 in_x, 578 in_x,
579 in_y, 579 in_y,
580 in_w, 580 in_w,
581 in_h); 581 in_h);
582 file->last_type_read = 2; 582 file->last_type_read = 2;
583 file->last_stream_read = stream; 583 file->last_stream_read = stream;
584 file->vtrack[stream]->current_position++; 584 file->vtrack[stream]->current_position++;
585 } 585 }
586//printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer)); 586//printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
587 return result; 587 return result;
588} 588}
589 589
590 590
591int mpeg3_read_audio(mpeg3_t *file, 591int mpeg3_read_audio(mpeg3_t *file,
592 mpeg3_real_t *output_f, 592 mpeg3_real_t *output_f,
593 short *output_i, int sampleSpacing, 593 short *output_i, int sampleSpacing,
594 int channel, 594 int channel,
595 long samples, 595 long samples,
596 int stream) 596 int stream)
597{ 597{
598 int result = -1; 598 int result = -1;
599 599
600//printf("mpeg3_read_audio 1 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer)); 600//printf("mpeg3_read_audio 1 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
601 if(file->has_audio) 601 if(file->has_audio)
602 { 602 {
603 result = mpeg3audio_decode_audio(file->atrack[stream]->audio, 603 result = mpeg3audio_decode_audio(file->atrack[stream]->audio,
604 output_f, 604 output_f,
605 output_i, sampleSpacing, 605 output_i, sampleSpacing,
606 channel, 606 channel,
607 file->atrack[stream]->current_position, 607 file->atrack[stream]->current_position,
608 samples); 608 samples);
609 file->last_type_read = 1; 609 file->last_type_read = 1;
610 file->last_stream_read = stream; 610 file->last_stream_read = stream;
611 file->atrack[stream]->current_position += samples; 611 file->atrack[stream]->current_position += samples;
612 } 612 }
613//printf("mpeg3_read_audio 2 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer)); 613//printf("mpeg3_read_audio 2 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
614 614
615 return result; 615 return result;
616} 616}
617 617
618int mpeg3_reread_audio(mpeg3_t *file, 618int mpeg3_reread_audio(mpeg3_t *file,
619 mpeg3_real_t *output_f, 619 mpeg3_real_t *output_f,
620 short *output_i, int sampleSpacing, 620 short *output_i, int sampleSpacing,
621 int channel, 621 int channel,
622 long samples, 622 long samples,
623 int stream) 623 int stream)
624{ 624{
625 if(file->has_audio) 625 if(file->has_audio)
626 { 626 {
627 mpeg3_set_sample(file, 627 mpeg3_set_sample(file,
628 file->atrack[stream]->current_position - samples, 628 file->atrack[stream]->current_position - samples,
629 stream); 629 stream);
630 file->last_type_read = 1; 630 file->last_type_read = 1;
631 file->last_stream_read = stream; 631 file->last_stream_read = stream;
632 return mpeg3_read_audio(file, 632 return mpeg3_read_audio(file,
633 output_f, 633 output_f,
634 output_i, sampleSpacing, 634 output_i, sampleSpacing,
635 channel, 635 channel,
636 samples, 636 samples,
637 stream); 637 stream);
638 } 638 }
639 return -1; 639 return -1;
640} 640}
641 641
642int mpeg3_read_audio_chunk(mpeg3_t *file, 642int mpeg3_read_audio_chunk(mpeg3_t *file,
643 unsigned char *output, 643 unsigned char *output,
644 long *size, 644 long *size,
645 long max_size, 645 long max_size,
646 int stream) 646 int stream)
647{ 647{
648 int result = 0; 648 int result = 0;
649 if(file->has_audio) 649 if(file->has_audio)
650 { 650 {
651 result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size); 651 result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size);
652 file->last_type_read = 1; 652 file->last_type_read = 1;
653 file->last_stream_read = stream; 653 file->last_stream_read = stream;
654 } 654 }
655 return result; 655 return result;
656} 656}
657 657
658int mpeg3_read_video_chunk(mpeg3_t *file, 658int mpeg3_read_video_chunk(mpeg3_t *file,
659 unsigned char *output, 659 unsigned char *output,
660 long *size, 660 long *size,
661 long max_size, 661 long max_size,
662 int stream) 662 int stream)
663{ 663{
664 int result = 0; 664 int result = 0;
665 if(file->has_video) 665 if(file->has_video)
666 { 666 {
667 result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size); 667 result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size);
668 file->last_type_read = 2; 668 file->last_type_read = 2;
669 file->last_stream_read = stream; 669 file->last_stream_read = stream;
670 } 670 }
671 return result; 671 return result;
672} 672}
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp
index be47eb2..93719bc 100644
--- a/libopie2/opieui/oimageeffect.cpp
+++ b/libopie2/opieui/oimageeffect.cpp
@@ -1,3773 +1,3776 @@
1/* This file is part of the KDE libraries 1/* This file is part of the KDE libraries
2 Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org> 2 Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org>
3 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> 3 (C) 1998, 1999 Christian Tibirna <ctibirna@total.net>
4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> 4 (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org>
5 (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> 5 (C) 2000 Josef Weidendorfer <weidendo@in.tum.de>
6 6
7Redistribution and use in source and binary forms, with or without 7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions 8modification, are permitted provided that the following conditions
9are met: 9are met:
10 10
111. Redistributions of source code must retain the above copyright 111. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer. 12 notice, this list of conditions and the following disclaimer.
132. Redistributions in binary form must reproduce the above copyright 132. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the 14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution. 15 documentation and/or other materials provided with the distribution.
16 16
17THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28*/ 28*/
29 29
30// $Id$ 30// $Id$
31 31
32#include <math.h> 32#include <math.h>
33 33
34#include <qimage.h> 34#include <qimage.h>
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37#include <opie2/oimageeffect.h> 37#include <opie2/oimageeffect.h>
38#include <opie2/odebug.h> 38#include <opie2/odebug.h>
39 39
40#define MaxRGB 255L 40#define MaxRGB 255L
41#define DegreesToRadians(x) ((x)*M_PI/180.0) 41#define DegreesToRadians(x) ((x)*M_PI/180.0)
42 42
43using namespace std; 43using namespace std;
44using namespace Opie::Core; 44using namespace Opie::Core;
45 45
46namespace Opie { 46namespace Opie {
47namespace Ui { 47namespace Ui {
48 48
49inline unsigned int intensityValue(unsigned int color) 49inline unsigned int intensityValue(unsigned int color)
50{ 50{
51 return((unsigned int)((0.299*qRed(color) + 51 return((unsigned int)((0.299*qRed(color) +
52 0.587*qGreen(color) + 52 0.587*qGreen(color) +
53 0.1140000000000001*qBlue(color)))); 53 0.1140000000000001*qBlue(color))));
54} 54}
55 55
56//====================================================================== 56//======================================================================
57// 57//
58// Gradient effects 58// Gradient effects
59// 59//
60//====================================================================== 60//======================================================================
61 61
62QImage OImageEffect::gradient(const QSize &size, const QColor &ca, 62QImage OImageEffect::gradient(const QSize &size, const QColor &ca,
63 const QColor &cb, GradientType eff, int ncols) 63 const QColor &cb, GradientType eff, int ncols)
64{ 64{
65 int rDiff, gDiff, bDiff; 65 int rDiff, gDiff, bDiff;
66 int rca, gca, bca, rcb, gcb, bcb; 66 int rca, gca, bca, rcb, gcb, bcb;
67 67
68 QImage image(size, 32); 68 QImage image(size, 32);
69 69
70 if (size.width() == 0 || size.height() == 0) { 70 if (size.width() == 0 || size.height() == 0) {
71 odebug << "WARNING: OImageEffect::gradient: invalid image" << oendl; 71 odebug << "WARNING: OImageEffect::gradient: invalid image" << oendl;
72 return image; 72 return image;
73 } 73 }
74 74
75 register int x, y; 75 register int x, y;
76 76
77 rDiff = (rcb = cb.red()) - (rca = ca.red()); 77 rDiff = (rcb = cb.red()) - (rca = ca.red());
78 gDiff = (gcb = cb.green()) - (gca = ca.green()); 78 gDiff = (gcb = cb.green()) - (gca = ca.green());
79 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 79 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
80 80
81 if( eff == VerticalGradient || eff == HorizontalGradient ){ 81 if( eff == VerticalGradient || eff == HorizontalGradient ){
82 82
83 uint *p; 83 uint *p;
84 uint rgb; 84 uint rgb;
85 85
86 register int rl = rca << 16; 86 register int rl = rca << 16;
87 register int gl = gca << 16; 87 register int gl = gca << 16;
88 register int bl = bca << 16; 88 register int bl = bca << 16;
89 89
90 if( eff == VerticalGradient ) { 90 if( eff == VerticalGradient ) {
91 91
92 int rcdelta = ((1<<16) / size.height()) * rDiff; 92 int rcdelta = ((1<<16) / size.height()) * rDiff;
93 int gcdelta = ((1<<16) / size.height()) * gDiff; 93 int gcdelta = ((1<<16) / size.height()) * gDiff;
94 int bcdelta = ((1<<16) / size.height()) * bDiff; 94 int bcdelta = ((1<<16) / size.height()) * bDiff;
95 95
96 for ( y = 0; y < size.height(); y++ ) { 96 for ( y = 0; y < size.height(); y++ ) {
97 p = (uint *) image.scanLine(y); 97 p = (uint *) image.scanLine(y);
98 98
99 rl += rcdelta; 99 rl += rcdelta;
100 gl += gcdelta; 100 gl += gcdelta;
101 bl += bcdelta; 101 bl += bcdelta;
102 102
103 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); 103 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) );
104 104
105 for( x = 0; x < size.width(); x++ ) { 105 for( x = 0; x < size.width(); x++ ) {
106 *p = rgb; 106 *p = rgb;
107 p++; 107 p++;
108 } 108 }
109 } 109 }
110 110
111 } 111 }
112 else { // must be HorizontalGradient 112 else { // must be HorizontalGradient
113 113
114 unsigned int *o_src = (unsigned int *)image.scanLine(0); 114 unsigned int *o_src = (unsigned int *)image.scanLine(0);
115 unsigned int *src = o_src; 115 unsigned int *src = o_src;
116 116
117 int rcdelta = ((1<<16) / size.width()) * rDiff; 117 int rcdelta = ((1<<16) / size.width()) * rDiff;
118 int gcdelta = ((1<<16) / size.width()) * gDiff; 118 int gcdelta = ((1<<16) / size.width()) * gDiff;
119 int bcdelta = ((1<<16) / size.width()) * bDiff; 119 int bcdelta = ((1<<16) / size.width()) * bDiff;
120 120
121 for( x = 0; x < size.width(); x++) { 121 for( x = 0; x < size.width(); x++) {
122 122
123 rl += rcdelta; 123 rl += rcdelta;
124 gl += gcdelta; 124 gl += gcdelta;
125 bl += bcdelta; 125 bl += bcdelta;
126 126
127 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); 127 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16));
128 } 128 }
129 129
130 src = o_src; 130 src = o_src;
131 131
132 // Believe it or not, manually copying in a for loop is faster 132 // Believe it or not, manually copying in a for loop is faster
133 // than calling memcpy for each scanline (on the order of ms...). 133 // than calling memcpy for each scanline (on the order of ms...).
134 // I think this is due to the function call overhead (mosfet). 134 // I think this is due to the function call overhead (mosfet).
135 135
136 for (y = 1; y < size.height(); ++y) { 136 for (y = 1; y < size.height(); ++y) {
137 137
138 p = (unsigned int *)image.scanLine(y); 138 p = (unsigned int *)image.scanLine(y);
139 src = o_src; 139 src = o_src;
140 for(x=0; x < size.width(); ++x) 140 for(x=0; x < size.width(); ++x)
141 *p++ = *src++; 141 *p++ = *src++;
142 } 142 }
143 } 143 }
144 } 144 }
145 145
146 else { 146 else {
147 147
148 float rfd, gfd, bfd; 148 float rfd, gfd, bfd;
149 float rd = rca, gd = gca, bd = bca; 149 float rd = rca, gd = gca, bd = bca;
150 150
151 unsigned char *xtable[3]; 151 unsigned char *xtable[3];
152 unsigned char *ytable[3]; 152 unsigned char *ytable[3];
153 153
154 unsigned int w = size.width(), h = size.height(); 154 unsigned int w = size.width(), h = size.height();
155 xtable[0] = new unsigned char[w]; 155 xtable[0] = new unsigned char[w];
156 xtable[1] = new unsigned char[w]; 156 xtable[1] = new unsigned char[w];
157 xtable[2] = new unsigned char[w]; 157 xtable[2] = new unsigned char[w];
158 ytable[0] = new unsigned char[h]; 158 ytable[0] = new unsigned char[h];
159 ytable[1] = new unsigned char[h]; 159 ytable[1] = new unsigned char[h];
160 ytable[2] = new unsigned char[h]; 160 ytable[2] = new unsigned char[h];
161 w*=2, h*=2; 161 w*=2, h*=2;
162 162
163 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { 163 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) {
164 // Diagonal dgradient code inspired by BlackBox (mosfet) 164 // Diagonal dgradient code inspired by BlackBox (mosfet)
165 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and 165 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and
166 // Mike Cole <mike@mydot.com>. 166 // Mike Cole <mike@mydot.com>.
167 167
168 rfd = (float)rDiff/w; 168 rfd = (float)rDiff/w;
169 gfd = (float)gDiff/w; 169 gfd = (float)gDiff/w;
170 bfd = (float)bDiff/w; 170 bfd = (float)bDiff/w;
171 171
172 int dir; 172 int dir;
173 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { 173 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) {
174 dir = eff == DiagonalGradient? x : size.width() - x - 1; 174 dir = eff == DiagonalGradient? x : size.width() - x - 1;
175 xtable[0][dir] = (unsigned char) rd; 175 xtable[0][dir] = (unsigned char) rd;
176 xtable[1][dir] = (unsigned char) gd; 176 xtable[1][dir] = (unsigned char) gd;
177 xtable[2][dir] = (unsigned char) bd; 177 xtable[2][dir] = (unsigned char) bd;
178 } 178 }
179 rfd = (float)rDiff/h; 179 rfd = (float)rDiff/h;
180 gfd = (float)gDiff/h; 180 gfd = (float)gDiff/h;
181 bfd = (float)bDiff/h; 181 bfd = (float)bDiff/h;
182 rd = gd = bd = 0; 182 rd = gd = bd = 0;
183 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { 183 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) {
184 ytable[0][y] = (unsigned char) rd; 184 ytable[0][y] = (unsigned char) rd;
185 ytable[1][y] = (unsigned char) gd; 185 ytable[1][y] = (unsigned char) gd;
186 ytable[2][y] = (unsigned char) bd; 186 ytable[2][y] = (unsigned char) bd;
187 } 187 }
188 188
189 for (y = 0; y < size.height(); y++) { 189 for (y = 0; y < size.height(); y++) {
190 unsigned int *scanline = (unsigned int *)image.scanLine(y); 190 unsigned int *scanline = (unsigned int *)image.scanLine(y);
191 for (x = 0; x < size.width(); x++) { 191 for (x = 0; x < size.width(); x++) {
192 scanline[x] = qRgb(xtable[0][x] + ytable[0][y], 192 scanline[x] = qRgb(xtable[0][x] + ytable[0][y],
193 xtable[1][x] + ytable[1][y], 193 xtable[1][x] + ytable[1][y],
194 xtable[2][x] + ytable[2][y]); 194 xtable[2][x] + ytable[2][y]);
195 } 195 }
196 } 196 }
197 } 197 }
198 198
199 else if (eff == RectangleGradient || 199 else if (eff == RectangleGradient ||
200 eff == PyramidGradient || 200 eff == PyramidGradient ||
201 eff == PipeCrossGradient || 201 eff == PipeCrossGradient ||
202 eff == EllipticGradient) 202 eff == EllipticGradient)
203 { 203 {
204 int rSign = rDiff>0? 1: -1; 204 int rSign = rDiff>0? 1: -1;
205 int gSign = gDiff>0? 1: -1; 205 int gSign = gDiff>0? 1: -1;
206 int bSign = bDiff>0? 1: -1; 206 int bSign = bDiff>0? 1: -1;
207 207
208 rfd = (float)rDiff / size.width(); 208 rfd = (float)rDiff / size.width();
209 gfd = (float)gDiff / size.width(); 209 gfd = (float)gDiff / size.width();
210 bfd = (float)bDiff / size.width(); 210 bfd = (float)bDiff / size.width();
211 211
212 rd = (float)rDiff/2; 212 rd = (float)rDiff/2;
213 gd = (float)gDiff/2; 213 gd = (float)gDiff/2;
214 bd = (float)bDiff/2; 214 bd = (float)bDiff/2;
215 215
216 for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) 216 for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd)
217 { 217 {
218 xtable[0][x] = (unsigned char) abs((int)rd); 218 xtable[0][x] = (unsigned char) abs((int)rd);
219 xtable[1][x] = (unsigned char) abs((int)gd); 219 xtable[1][x] = (unsigned char) abs((int)gd);
220 xtable[2][x] = (unsigned char) abs((int)bd); 220 xtable[2][x] = (unsigned char) abs((int)bd);
221 } 221 }
222 222
223 rfd = (float)rDiff/size.height(); 223 rfd = (float)rDiff/size.height();
224 gfd = (float)gDiff/size.height(); 224 gfd = (float)gDiff/size.height();
225 bfd = (float)bDiff/size.height(); 225 bfd = (float)bDiff/size.height();
226 226
227 rd = (float)rDiff/2; 227 rd = (float)rDiff/2;
228 gd = (float)gDiff/2; 228 gd = (float)gDiff/2;
229 bd = (float)bDiff/2; 229 bd = (float)bDiff/2;
230 230
231 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) 231 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd)
232 { 232 {
233 ytable[0][y] = (unsigned char) abs((int)rd); 233 ytable[0][y] = (unsigned char) abs((int)rd);
234 ytable[1][y] = (unsigned char) abs((int)gd); 234 ytable[1][y] = (unsigned char) abs((int)gd);
235 ytable[2][y] = (unsigned char) abs((int)bd); 235 ytable[2][y] = (unsigned char) abs((int)bd);
236 } 236 }
237 unsigned int rgb; 237 unsigned int rgb;
238 int h = (size.height()+1)>>1; 238 int h = (size.height()+1)>>1;
239 for (y = 0; y < h; y++) { 239 for (y = 0; y < h; y++) {
240 unsigned int *sl1 = (unsigned int *)image.scanLine(y); 240 unsigned int *sl1 = (unsigned int *)image.scanLine(y);
241 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); 241 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y));
242 242
243 int w = (size.width()+1)>>1; 243 int w = (size.width()+1)>>1;
244 int x2 = size.width()-1; 244 int x2 = size.width()-1;
245 245
246 for (x = 0; x < w; x++, x2--) { 246 for (x = 0; x < w; x++, x2--) {
247 rgb = 0; 247 rgb = 0;
248 if (eff == PyramidGradient) { 248 if (eff == PyramidGradient) {
249 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 249 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
250 gcb-gSign*(xtable[1][x]+ytable[1][y]), 250 gcb-gSign*(xtable[1][x]+ytable[1][y]),
251 bcb-bSign*(xtable[2][x]+ytable[2][y])); 251 bcb-bSign*(xtable[2][x]+ytable[2][y]));
252 } 252 }
253 if (eff == RectangleGradient) { 253 if (eff == RectangleGradient) {
254 rgb = qRgb(rcb - rSign * 254 rgb = qRgb(rcb - rSign *
255 QMAX(xtable[0][x], ytable[0][y]) * 2, 255 QMAX(xtable[0][x], ytable[0][y]) * 2,
256 gcb - gSign * 256 gcb - gSign *
257 QMAX(xtable[1][x], ytable[1][y]) * 2, 257 QMAX(xtable[1][x], ytable[1][y]) * 2,
258 bcb - bSign * 258 bcb - bSign *
259 QMAX(xtable[2][x], ytable[2][y]) * 2); 259 QMAX(xtable[2][x], ytable[2][y]) * 2);
260 } 260 }
261 if (eff == PipeCrossGradient) { 261 if (eff == PipeCrossGradient) {
262 rgb = qRgb(rcb - rSign * 262 rgb = qRgb(rcb - rSign *
263 QMIN(xtable[0][x], ytable[0][y]) * 2, 263 QMIN(xtable[0][x], ytable[0][y]) * 2,
264 gcb - gSign * 264 gcb - gSign *
265 QMIN(xtable[1][x], ytable[1][y]) * 2, 265 QMIN(xtable[1][x], ytable[1][y]) * 2,
266 bcb - bSign * 266 bcb - bSign *
267 QMIN(xtable[2][x], ytable[2][y]) * 2); 267 QMIN(xtable[2][x], ytable[2][y]) * 2);
268 } 268 }
269 if (eff == EllipticGradient) { 269 if (eff == EllipticGradient) {
270 rgb = qRgb(rcb - rSign * 270 rgb = qRgb(rcb - rSign *
271 (int)sqrt((xtable[0][x]*xtable[0][x] + 271 (int)sqrt((xtable[0][x]*xtable[0][x] +
272 ytable[0][y]*ytable[0][y])*2.0), 272 ytable[0][y]*ytable[0][y])*2.0),
273 gcb - gSign * 273 gcb - gSign *
274 (int)sqrt((xtable[1][x]*xtable[1][x] + 274 (int)sqrt((xtable[1][x]*xtable[1][x] +
275 ytable[1][y]*ytable[1][y])*2.0), 275 ytable[1][y]*ytable[1][y])*2.0),
276 bcb - bSign * 276 bcb - bSign *
277 (int)sqrt((xtable[2][x]*xtable[2][x] + 277 (int)sqrt((xtable[2][x]*xtable[2][x] +
278 ytable[2][y]*ytable[2][y])*2.0)); 278 ytable[2][y]*ytable[2][y])*2.0));
279 } 279 }
280 280
281 sl1[x] = sl2[x] = rgb; 281 sl1[x] = sl2[x] = rgb;
282 sl1[x2] = sl2[x2] = rgb; 282 sl1[x2] = sl2[x2] = rgb;
283 } 283 }
284 } 284 }
285 } 285 }
286 286
287 delete [] xtable[0]; 287 delete [] xtable[0];
288 delete [] xtable[1]; 288 delete [] xtable[1];
289 delete [] xtable[2]; 289 delete [] xtable[2];
290 delete [] ytable[0]; 290 delete [] ytable[0];
291 delete [] ytable[1]; 291 delete [] ytable[1];
292 delete [] ytable[2]; 292 delete [] ytable[2];
293 } 293 }
294 294
295 // dither if necessary 295 // dither if necessary
296 if (ncols && (QPixmap::defaultDepth() < 15 )) { 296 if (ncols && (QPixmap::defaultDepth() < 15 )) {
297 if ( ncols < 2 || ncols > 256 ) 297 if ( ncols < 2 || ncols > 256 )
298 ncols = 3; 298 ncols = 3;
299 QColor *dPal = new QColor[ncols]; 299 QColor *dPal = new QColor[ncols];
300 for (int i=0; i<ncols; i++) { 300 for (int i=0; i<ncols; i++) {
301 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 301 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
302 gca + gDiff * i / ( ncols - 1 ), 302 gca + gDiff * i / ( ncols - 1 ),
303 bca + bDiff * i / ( ncols - 1 ) ); 303 bca + bDiff * i / ( ncols - 1 ) );
304 } 304 }
305 dither(image, dPal, ncols); 305 dither(image, dPal, ncols);
306 delete [] dPal; 306 delete [] dPal;
307 } 307 }
308 308
309 return image; 309 return image;
310} 310}
311 311
312 312
313// ----------------------------------------------------------------------------- 313// -----------------------------------------------------------------------------
314 314
315//CT this was (before Dirk A. Mueller's speedup changes) 315//CT this was (before Dirk A. Mueller's speedup changes)
316// merely the same code as in the above method, but it's supposedly 316// merely the same code as in the above method, but it's supposedly
317// way less performant since it introduces a lot of supplementary tests 317// way less performant since it introduces a lot of supplementary tests
318// and simple math operations for the calculus of the balance. 318// and simple math operations for the calculus of the balance.
319// (surprizingly, it isn't less performant, in the contrary :-) 319// (surprizingly, it isn't less performant, in the contrary :-)
320// Yes, I could have merged them, but then the excellent performance of 320// Yes, I could have merged them, but then the excellent performance of
321// the balanced code would suffer with no other gain than a mere 321// the balanced code would suffer with no other gain than a mere
322// source code and byte code size economy. 322// source code and byte code size economy.
323 323
324QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca, 324QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca,
325 const QColor &cb, GradientType eff, int xfactor, int yfactor, 325 const QColor &cb, GradientType eff, int xfactor, int yfactor,
326 int ncols) 326 int ncols)
327{ 327{
328 int dir; // general parameter used for direction switches 328 int dir; // general parameter used for direction switches
329 329
330 bool _xanti = false , _yanti = false; 330 bool _xanti = false , _yanti = false;
331 331
332 if (xfactor < 0) _xanti = true; // negative on X direction 332 if (xfactor < 0) _xanti = true; // negative on X direction
333 if (yfactor < 0) _yanti = true; // negative on Y direction 333 if (yfactor < 0) _yanti = true; // negative on Y direction
334 334
335 xfactor = abs(xfactor); 335 xfactor = abs(xfactor);
336 yfactor = abs(yfactor); 336 yfactor = abs(yfactor);
337 337
338 if (!xfactor) xfactor = 1; 338 if (!xfactor) xfactor = 1;
339 if (!yfactor) yfactor = 1; 339 if (!yfactor) yfactor = 1;
340 340
341 if (xfactor > 200 ) xfactor = 200; 341 if (xfactor > 200 ) xfactor = 200;
342 if (yfactor > 200 ) yfactor = 200; 342 if (yfactor > 200 ) yfactor = 200;
343 343
344 344
345 // float xbal = xfactor/5000.; 345 // float xbal = xfactor/5000.;
346 // float ybal = yfactor/5000.; 346 // float ybal = yfactor/5000.;
347 float xbal = xfactor/30./size.width(); 347 float xbal = xfactor/30./size.width();
348 float ybal = yfactor/30./size.height(); 348 float ybal = yfactor/30./size.height();
349 float rat; 349 float rat;
350 350
351 int rDiff, gDiff, bDiff; 351 int rDiff, gDiff, bDiff;
352 int rca, gca, bca, rcb, gcb, bcb; 352 int rca, gca, bca, rcb, gcb, bcb;
353 353
354 QImage image(size, 32); 354 QImage image(size, 32);
355 355
356 if (size.width() == 0 || size.height() == 0) { 356 if (size.width() == 0 || size.height() == 0) {
357 odebug << "WARNING: OImageEffect::unbalancedGradient : invalid image" << oendl; 357 odebug << "WARNING: OImageEffect::unbalancedGradient : invalid image" << oendl;
358 return image; 358 return image;
359 } 359 }
360 360
361 register int x, y; 361 register int x, y;
362 unsigned int *scanline; 362 unsigned int *scanline;
363 363
364 rDiff = (rcb = cb.red()) - (rca = ca.red()); 364 rDiff = (rcb = cb.red()) - (rca = ca.red());
365 gDiff = (gcb = cb.green()) - (gca = ca.green()); 365 gDiff = (gcb = cb.green()) - (gca = ca.green());
366 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 366 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
367 367
368 if( eff == VerticalGradient || eff == HorizontalGradient){ 368 if( eff == VerticalGradient || eff == HorizontalGradient){
369 QColor cRow; 369 QColor cRow;
370 370
371 uint *p; 371 uint *p;
372 uint rgbRow; 372 uint rgbRow;
373 373
374 if( eff == VerticalGradient) { 374 if( eff == VerticalGradient) {
375 for ( y = 0; y < size.height(); y++ ) { 375 for ( y = 0; y < size.height(); y++ ) {
376 dir = _yanti ? y : size.height() - 1 - y; 376 dir = _yanti ? y : size.height() - 1 - y;
377 p = (uint *) image.scanLine(dir); 377 p = (uint *) image.scanLine(dir);
378 rat = 1 - exp( - (float)y * ybal ); 378 rat = 1 - exp( - (float)y * ybal );
379 379
380 cRow.setRgb( rcb - (int) ( rDiff * rat ), 380 cRow.setRgb( rcb - (int) ( rDiff * rat ),
381 gcb - (int) ( gDiff * rat ), 381 gcb - (int) ( gDiff * rat ),
382 bcb - (int) ( bDiff * rat ) ); 382 bcb - (int) ( bDiff * rat ) );
383 383
384 rgbRow = cRow.rgb(); 384 rgbRow = cRow.rgb();
385 385
386 for( x = 0; x < size.width(); x++ ) { 386 for( x = 0; x < size.width(); x++ ) {
387 *p = rgbRow; 387 *p = rgbRow;
388 p++; 388 p++;
389 } 389 }
390 } 390 }
391 } 391 }
392 else { 392 else {
393 393
394 unsigned int *src = (unsigned int *)image.scanLine(0); 394 unsigned int *src = (unsigned int *)image.scanLine(0);
395 for(x = 0; x < size.width(); x++ ) 395 for(x = 0; x < size.width(); x++ )
396 { 396 {
397 dir = _xanti ? x : size.width() - 1 - x; 397 dir = _xanti ? x : size.width() - 1 - x;
398 rat = 1 - exp( - (float)x * xbal ); 398 rat = 1 - exp( - (float)x * xbal );
399 399
400 src[dir] = qRgb(rcb - (int) ( rDiff * rat ), 400 src[dir] = qRgb(rcb - (int) ( rDiff * rat ),
401 gcb - (int) ( gDiff * rat ), 401 gcb - (int) ( gDiff * rat ),
402 bcb - (int) ( bDiff * rat )); 402 bcb - (int) ( bDiff * rat ));
403 } 403 }
404 404
405 // Believe it or not, manually copying in a for loop is faster 405 // Believe it or not, manually copying in a for loop is faster
406 // than calling memcpy for each scanline (on the order of ms...). 406 // than calling memcpy for each scanline (on the order of ms...).
407 // I think this is due to the function call overhead (mosfet). 407 // I think this is due to the function call overhead (mosfet).
408 408
409 for(y = 1; y < size.height(); ++y) 409 for(y = 1; y < size.height(); ++y)
410 { 410 {
411 scanline = (unsigned int *)image.scanLine(y); 411 scanline = (unsigned int *)image.scanLine(y);
412 for(x=0; x < size.width(); ++x) 412 for(x=0; x < size.width(); ++x)
413 scanline[x] = src[x]; 413 scanline[x] = src[x];
414 } 414 }
415 } 415 }
416 } 416 }
417 417
418 else { 418 else {
419 int w=size.width(), h=size.height(); 419 int w=size.width(), h=size.height();
420 420
421 unsigned char *xtable[3]; 421 unsigned char *xtable[3];
422 unsigned char *ytable[3]; 422 unsigned char *ytable[3];
423 xtable[0] = new unsigned char[w]; 423 xtable[0] = new unsigned char[w];
424 xtable[1] = new unsigned char[w]; 424 xtable[1] = new unsigned char[w];
425 xtable[2] = new unsigned char[w]; 425 xtable[2] = new unsigned char[w];
426 ytable[0] = new unsigned char[h]; 426 ytable[0] = new unsigned char[h];
427 ytable[1] = new unsigned char[h]; 427 ytable[1] = new unsigned char[h];
428 ytable[2] = new unsigned char[h]; 428 ytable[2] = new unsigned char[h];
429 429
430 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) 430 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient)
431 { 431 {
432 for (x = 0; x < w; x++) { 432 for (x = 0; x < w; x++) {
433 dir = _xanti ? x : w - 1 - x; 433 dir = _xanti ? x : w - 1 - x;
434 rat = 1 - exp( - (float)x * xbal ); 434 rat = 1 - exp( - (float)x * xbal );
435 435
436 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 436 xtable[0][dir] = (unsigned char) ( rDiff/2 * rat );
437 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 437 xtable[1][dir] = (unsigned char) ( gDiff/2 * rat );
438 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 438 xtable[2][dir] = (unsigned char) ( bDiff/2 * rat );
439 } 439 }
440 440
441 for (y = 0; y < h; y++) { 441 for (y = 0; y < h; y++) {
442 dir = _yanti ? y : h - 1 - y; 442 dir = _yanti ? y : h - 1 - y;
443 rat = 1 - exp( - (float)y * ybal ); 443 rat = 1 - exp( - (float)y * ybal );
444 444
445 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat ); 445 ytable[0][dir] = (unsigned char) ( rDiff/2 * rat );
446 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat ); 446 ytable[1][dir] = (unsigned char) ( gDiff/2 * rat );
447 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat ); 447 ytable[2][dir] = (unsigned char) ( bDiff/2 * rat );
448 } 448 }
449 449
450 for (y = 0; y < h; y++) { 450 for (y = 0; y < h; y++) {
451 unsigned int *scanline = (unsigned int *)image.scanLine(y); 451 unsigned int *scanline = (unsigned int *)image.scanLine(y);
452 for (x = 0; x < w; x++) { 452 for (x = 0; x < w; x++) {
453 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]), 453 scanline[x] = qRgb(rcb - (xtable[0][x] + ytable[0][y]),
454 gcb - (xtable[1][x] + ytable[1][y]), 454 gcb - (xtable[1][x] + ytable[1][y]),
455 bcb - (xtable[2][x] + ytable[2][y])); 455 bcb - (xtable[2][x] + ytable[2][y]));
456 } 456 }
457 } 457 }
458 } 458 }
459 459
460 else if (eff == RectangleGradient || 460 else if (eff == RectangleGradient ||
461 eff == PyramidGradient || 461 eff == PyramidGradient ||
462 eff == PipeCrossGradient || 462 eff == PipeCrossGradient ||
463 eff == EllipticGradient) 463 eff == EllipticGradient)
464 { 464 {
465 int rSign = rDiff>0? 1: -1; 465 int rSign = rDiff>0? 1: -1;
466 int gSign = gDiff>0? 1: -1; 466 int gSign = gDiff>0? 1: -1;
467 int bSign = bDiff>0? 1: -1; 467 int bSign = bDiff>0? 1: -1;
468 468
469 for (x = 0; x < w; x++) 469 for (x = 0; x < w; x++)
470 { 470 {
471 dir = _xanti ? x : w - 1 - x; 471 dir = _xanti ? x : w - 1 - x;
472 rat = 1 - exp( - (float)x * xbal ); 472 rat = 1 - exp( - (float)x * xbal );
473 473
474 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 474 xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
475 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 475 xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
476 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 476 xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
477 } 477 }
478 478
479 for (y = 0; y < h; y++) 479 for (y = 0; y < h; y++)
480 { 480 {
481 dir = _yanti ? y : h - 1 - y; 481 dir = _yanti ? y : h - 1 - y;
482 482
483 rat = 1 - exp( - (float)y * ybal ); 483 rat = 1 - exp( - (float)y * ybal );
484 484
485 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); 485 ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat)));
486 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); 486 ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat)));
487 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); 487 ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat)));
488 } 488 }
489 489
490 for (y = 0; y < h; y++) { 490 for (y = 0; y < h; y++) {
491 unsigned int *scanline = (unsigned int *)image.scanLine(y); 491 unsigned int *scanline = (unsigned int *)image.scanLine(y);
492 for (x = 0; x < w; x++) { 492 for (x = 0; x < w; x++) {
493 if (eff == PyramidGradient) 493 if (eff == PyramidGradient)
494 { 494 {
495 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), 495 scanline[x] = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
496 gcb-gSign*(xtable[1][x]+ytable[1][y]), 496 gcb-gSign*(xtable[1][x]+ytable[1][y]),
497 bcb-bSign*(xtable[2][x]+ytable[2][y])); 497 bcb-bSign*(xtable[2][x]+ytable[2][y]));
498 } 498 }
499 if (eff == RectangleGradient) 499 if (eff == RectangleGradient)
500 { 500 {
501 scanline[x] = qRgb(rcb - rSign * 501 scanline[x] = qRgb(rcb - rSign *
502 QMAX(xtable[0][x], ytable[0][y]) * 2, 502 QMAX(xtable[0][x], ytable[0][y]) * 2,
503 gcb - gSign * 503 gcb - gSign *
504 QMAX(xtable[1][x], ytable[1][y]) * 2, 504 QMAX(xtable[1][x], ytable[1][y]) * 2,
505 bcb - bSign * 505 bcb - bSign *
506 QMAX(xtable[2][x], ytable[2][y]) * 2); 506 QMAX(xtable[2][x], ytable[2][y]) * 2);
507 } 507 }
508 if (eff == PipeCrossGradient) 508 if (eff == PipeCrossGradient)
509 { 509 {
510 scanline[x] = qRgb(rcb - rSign * 510 scanline[x] = qRgb(rcb - rSign *
511 QMIN(xtable[0][x], ytable[0][y]) * 2, 511 QMIN(xtable[0][x], ytable[0][y]) * 2,
512 gcb - gSign * 512 gcb - gSign *
513 QMIN(xtable[1][x], ytable[1][y]) * 2, 513 QMIN(xtable[1][x], ytable[1][y]) * 2,
514 bcb - bSign * 514 bcb - bSign *
515 QMIN(xtable[2][x], ytable[2][y]) * 2); 515 QMIN(xtable[2][x], ytable[2][y]) * 2);
516 } 516 }
517 if (eff == EllipticGradient) 517 if (eff == EllipticGradient)
518 { 518 {
519 scanline[x] = qRgb(rcb - rSign * 519 scanline[x] = qRgb(rcb - rSign *
520 (int)sqrt((xtable[0][x]*xtable[0][x] + 520 (int)sqrt((xtable[0][x]*xtable[0][x] +
521 ytable[0][y]*ytable[0][y])*2.0), 521 ytable[0][y]*ytable[0][y])*2.0),
522 gcb - gSign * 522 gcb - gSign *
523 (int)sqrt((xtable[1][x]*xtable[1][x] + 523 (int)sqrt((xtable[1][x]*xtable[1][x] +
524 ytable[1][y]*ytable[1][y])*2.0), 524 ytable[1][y]*ytable[1][y])*2.0),
525 bcb - bSign * 525 bcb - bSign *
526 (int)sqrt((xtable[2][x]*xtable[2][x] + 526 (int)sqrt((xtable[2][x]*xtable[2][x] +
527 ytable[2][y]*ytable[2][y])*2.0)); 527 ytable[2][y]*ytable[2][y])*2.0));
528 } 528 }
529 } 529 }
530 } 530 }
531 } 531 }
532 532
533 if (ncols && (QPixmap::defaultDepth() < 15 )) { 533 if (ncols && (QPixmap::defaultDepth() < 15 )) {
534 if ( ncols < 2 || ncols > 256 ) 534 if ( ncols < 2 || ncols > 256 )
535 ncols = 3; 535 ncols = 3;
536 QColor *dPal = new QColor[ncols]; 536 QColor *dPal = new QColor[ncols];
537 for (int i=0; i<ncols; i++) { 537 for (int i=0; i<ncols; i++) {
538 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), 538 dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ),
539 gca + gDiff * i / ( ncols - 1 ), 539 gca + gDiff * i / ( ncols - 1 ),
540 bca + bDiff * i / ( ncols - 1 ) ); 540 bca + bDiff * i / ( ncols - 1 ) );
541 } 541 }
542 dither(image, dPal, ncols); 542 dither(image, dPal, ncols);
543 delete [] dPal; 543 delete [] dPal;
544 } 544 }
545 545
546 delete [] xtable[0]; 546 delete [] xtable[0];
547 delete [] xtable[1]; 547 delete [] xtable[1];
548 delete [] xtable[2]; 548 delete [] xtable[2];
549 delete [] ytable[0]; 549 delete [] ytable[0];
550 delete [] ytable[1]; 550 delete [] ytable[1];
551 delete [] ytable[2]; 551 delete [] ytable[2];
552 552
553 } 553 }
554 554
555 return image; 555 return image;
556} 556}
557 557
558 558
559//====================================================================== 559//======================================================================
560// 560//
561// Intensity effects 561// Intensity effects
562// 562//
563//====================================================================== 563//======================================================================
564 564
565 565
566/* This builds a 256 byte unsigned char lookup table with all 566/* This builds a 256 byte unsigned char lookup table with all
567 * the possible percent values prior to applying the effect, then uses 567 * the possible percent values prior to applying the effect, then uses
568 * integer math for the pixels. For any image larger than 9x9 this will be 568 * integer math for the pixels. For any image larger than 9x9 this will be
569 * less expensive than doing a float operation on the 3 color components of 569 * less expensive than doing a float operation on the 3 color components of
570 * each pixel. (mosfet) 570 * each pixel. (mosfet)
571 */ 571 */
572 572
573QImage& OImageEffect::intensity(QImage &image, float percent) 573QImage& OImageEffect::intensity(QImage &image, float percent)
574{ 574{
575 if (image.width() == 0 || image.height() == 0) { 575 if (image.width() == 0 || image.height() == 0) {
576 odebug << "WARNING: OImageEffect::intensity : invalid image" << oendl; 576 odebug << "WARNING: OImageEffect::intensity : invalid image" << oendl;
577 return image; 577 return image;
578 } 578 }
579 579
580 int segColors = image.depth() > 8 ? 256 : image.numColors(); 580 int segColors = image.depth() > 8 ? 256 : image.numColors();
581 unsigned char *segTbl = new unsigned char[segColors]; 581 unsigned char *segTbl = new unsigned char[segColors];
582 int pixels = image.depth() > 8 ? image.width()*image.height() : 582 int pixels = image.depth() > 8 ? image.width()*image.height() :
583 image.numColors(); 583 image.numColors();
584 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 584 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
585 (unsigned int *)image.colorTable(); 585 (unsigned int *)image.colorTable();
586 586
587 bool brighten = (percent >= 0); 587 bool brighten = (percent >= 0);
588 if(percent < 0) 588 if(percent < 0)
589 percent = -percent; 589 percent = -percent;
590 590
591 if(brighten){ // keep overflow check out of loops 591 if(brighten){ // keep overflow check out of loops
592 for(int i=0; i < segColors; ++i){ 592 for(int i=0; i < segColors; ++i){
593 int tmp = (int)(i*percent); 593 int tmp = (int)(i*percent);
594 if(tmp > 255) 594 if(tmp > 255)
595 tmp = 255; 595 tmp = 255;
596 segTbl[i] = tmp; 596 segTbl[i] = tmp;
597 } 597 }
598 } 598 }
599 else{ 599 else{
600 for(int i=0; i < segColors; ++i){ 600 for(int i=0; i < segColors; ++i){
601 int tmp = (int)(i*percent); 601 int tmp = (int)(i*percent);
602 if(tmp < 0) 602 if(tmp < 0)
603 tmp = 0; 603 tmp = 0;
604 segTbl[i] = tmp; 604 segTbl[i] = tmp;
605 } 605 }
606 } 606 }
607 607
608 if(brighten){ // same here 608 if(brighten){ // same here
609 for(int i=0; i < pixels; ++i){ 609 for(int i=0; i < pixels; ++i){
610 int r = qRed(data[i]); 610 int r = qRed(data[i]);
611 int g = qGreen(data[i]); 611 int g = qGreen(data[i]);
612 int b = qBlue(data[i]); 612 int b = qBlue(data[i]);
613 int a = qAlpha(data[i]); 613 int a = qAlpha(data[i]);
614 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; 614 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
615 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; 615 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
616 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; 616 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
617 data[i] = qRgba(r, g, b,a); 617 data[i] = qRgba(r, g, b,a);
618 } 618 }
619 } 619 }
620 else{ 620 else{
621 for(int i=0; i < pixels; ++i){ 621 for(int i=0; i < pixels; ++i){
622 int r = qRed(data[i]); 622 int r = qRed(data[i]);
623 int g = qGreen(data[i]); 623 int g = qGreen(data[i]);
624 int b = qBlue(data[i]); 624 int b = qBlue(data[i]);
625 int a = qAlpha(data[i]); 625 int a = qAlpha(data[i]);
626 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; 626 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
627 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; 627 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
628 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; 628 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
629 data[i] = qRgba(r, g, b, a); 629 data[i] = qRgba(r, g, b, a);
630 } 630 }
631 } 631 }
632 delete [] segTbl; 632 delete [] segTbl;
633 633
634 return image; 634 return image;
635} 635}
636 636
637QImage& OImageEffect::channelIntensity(QImage &image, float percent, 637QImage& OImageEffect::channelIntensity(QImage &image, float percent,
638 RGBComponent channel) 638 RGBComponent channel)
639{ 639{
640 if (image.width() == 0 || image.height() == 0) { 640 if (image.width() == 0 || image.height() == 0) {
641 odebug << "WARNING: OImageEffect::channelIntensity : invalid image" << oendl; 641 odebug << "WARNING: OImageEffect::channelIntensity : invalid image" << oendl;
642 return image; 642 return image;
643 } 643 }
644 644
645 int segColors = image.depth() > 8 ? 256 : image.numColors(); 645 int segColors = image.depth() > 8 ? 256 : image.numColors();
646 unsigned char *segTbl = new unsigned char[segColors]; 646 unsigned char *segTbl = new unsigned char[segColors];
647 int pixels = image.depth() > 8 ? image.width()*image.height() : 647 int pixels = image.depth() > 8 ? image.width()*image.height() :
648 image.numColors(); 648 image.numColors();
649 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 649 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
650 (unsigned int *)image.colorTable(); 650 (unsigned int *)image.colorTable();
651 bool brighten = (percent >= 0); 651 bool brighten = (percent >= 0);
652 if(percent < 0) 652 if(percent < 0)
653 percent = -percent; 653 percent = -percent;
654 654
655 if(brighten){ // keep overflow check out of loops 655 if(brighten){ // keep overflow check out of loops
656 for(int i=0; i < segColors; ++i){ 656 for(int i=0; i < segColors; ++i){
657 int tmp = (int)(i*percent); 657 int tmp = (int)(i*percent);
658 if(tmp > 255) 658 if(tmp > 255)
659 tmp = 255; 659 tmp = 255;
660 segTbl[i] = tmp; 660 segTbl[i] = tmp;
661 } 661 }
662 } 662 }
663 else{ 663 else{
664 for(int i=0; i < segColors; ++i){ 664 for(int i=0; i < segColors; ++i){
665 int tmp = (int)(i*percent); 665 int tmp = (int)(i*percent);
666 if(tmp < 0) 666 if(tmp < 0)
667 tmp = 0; 667 tmp = 0;
668 segTbl[i] = tmp; 668 segTbl[i] = tmp;
669 } 669 }
670 } 670 }
671 671
672 if(brighten){ // same here 672 if(brighten){ // same here
673 if(channel == Red){ // and here ;-) 673 if(channel == Red){ // and here ;-)
674 for(int i=0; i < pixels; ++i){ 674 for(int i=0; i < pixels; ++i){
675 int c = qRed(data[i]); 675 int c = qRed(data[i]);
676 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 676 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
677 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 677 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
678 } 678 }
679 } 679 }
680 if(channel == Green){ 680 if(channel == Green){
681 for(int i=0; i < pixels; ++i){ 681 for(int i=0; i < pixels; ++i){
682 int c = qGreen(data[i]); 682 int c = qGreen(data[i]);
683 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 683 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
684 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 684 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
685 } 685 }
686 } 686 }
687 else{ 687 else{
688 for(int i=0; i < pixels; ++i){ 688 for(int i=0; i < pixels; ++i){
689 int c = qBlue(data[i]); 689 int c = qBlue(data[i]);
690 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; 690 c = c + segTbl[c] > 255 ? 255 : c + segTbl[c];
691 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 691 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
692 } 692 }
693 } 693 }
694 694
695 } 695 }
696 else{ 696 else{
697 if(channel == Red){ 697 if(channel == Red){
698 for(int i=0; i < pixels; ++i){ 698 for(int i=0; i < pixels; ++i){
699 int c = qRed(data[i]); 699 int c = qRed(data[i]);
700 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 700 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
701 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i])); 701 data[i] = qRgba(c, qGreen(data[i]), qBlue(data[i]), qAlpha(data[i]));
702 } 702 }
703 } 703 }
704 if(channel == Green){ 704 if(channel == Green){
705 for(int i=0; i < pixels; ++i){ 705 for(int i=0; i < pixels; ++i){
706 int c = qGreen(data[i]); 706 int c = qGreen(data[i]);
707 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 707 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
708 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i])); 708 data[i] = qRgba(qRed(data[i]), c, qBlue(data[i]), qAlpha(data[i]));
709 } 709 }
710 } 710 }
711 else{ 711 else{
712 for(int i=0; i < pixels; ++i){ 712 for(int i=0; i < pixels; ++i){
713 int c = qBlue(data[i]); 713 int c = qBlue(data[i]);
714 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; 714 c = c - segTbl[c] < 0 ? 0 : c - segTbl[c];
715 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i])); 715 data[i] = qRgba(qRed(data[i]), qGreen(data[i]), c, qAlpha(data[i]));
716 } 716 }
717 } 717 }
718 } 718 }
719 delete [] segTbl; 719 delete [] segTbl;
720 720
721 return image; 721 return image;
722} 722}
723 723
724// Modulate an image with an RBG channel of another image 724// Modulate an image with an RBG channel of another image
725// 725//
726QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse, 726QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse,
727 ModulationType type, int factor, RGBComponent channel) 727 ModulationType type, int factor, RGBComponent channel)
728{ 728{
729 if (image.width() == 0 || image.height() == 0 || 729 if (image.width() == 0 || image.height() == 0 ||
730 modImage.width() == 0 || modImage.height() == 0) { 730 modImage.width() == 0 || modImage.height() == 0) {
731 odebug << "WARNING: OImageEffect::modulate : invalid image" << oendl; 731 odebug << "WARNING: OImageEffect::modulate : invalid image" << oendl;
732 return image; 732 return image;
733 } 733 }
734 734
735 int r, g, b, h, s, v, a; 735 int r, g, b, h, s, v, a;
736 QColor clr; 736 QColor clr;
737 int mod=0; 737 int mod=0;
738 unsigned int x1, x2, y1, y2; 738 unsigned int x1, x2, y1, y2;
739 register int x, y; 739 register int x, y;
740 740
741 // for image, we handle only depth 32 741 // for image, we handle only depth 32
742 if (image.depth()<32) image = image.convertDepth(32); 742 if (image.depth()<32) image = image.convertDepth(32);
743 743
744 // for modImage, we handle depth 8 and 32 744 // for modImage, we handle depth 8 and 32
745 if (modImage.depth()<8) modImage = modImage.convertDepth(8); 745 if (modImage.depth()<8) modImage = modImage.convertDepth(8);
746 746
747 unsigned int *colorTable2 = (modImage.depth()==8) ? 747 unsigned int *colorTable2 = (modImage.depth()==8) ?
748 modImage.colorTable():0; 748 modImage.colorTable():0;
749 unsigned int *data1, *data2; 749 unsigned int *data1, *data2;
750 unsigned char *data2b; 750 unsigned char *data2b;
751 unsigned int color1, color2; 751 unsigned int color1, color2;
752 752
753 x1 = image.width(); y1 = image.height(); 753 x1 = image.width(); y1 = image.height();
754 x2 = modImage.width(); y2 = modImage.height(); 754 x2 = modImage.width(); y2 = modImage.height();
755 755
756 for (y = 0; y < (int)y1; y++) { 756 for (y = 0; y < (int)y1; y++) {
757 data1 = (unsigned int *) image.scanLine(y); 757 data1 = (unsigned int *) image.scanLine(y);
758 data2 = (unsigned int *) modImage.scanLine( y%y2 ); 758 data2 = (unsigned int *) modImage.scanLine( y%y2 );
759 data2b = (unsigned char *) modImage.scanLine( y%y2 ); 759 data2b = (unsigned char *) modImage.scanLine( y%y2 );
760 760
761 x=0; 761 x=0;
762 while(x < (int)x1) { 762 while(x < (int)x1) {
763 color2 = (colorTable2) ? colorTable2[*data2b] : *data2; 763 color2 = (colorTable2) ? colorTable2[*data2b] : *data2;
764 if (reverse) { 764 if (reverse) {
765 color1 = color2; 765 color1 = color2;
766 color2 = *data1; 766 color2 = *data1;
767 } 767 }
768 else 768 else
769 color1 = *data1; 769 color1 = *data1;
770 770
771 if (type == Intensity || type == Contrast) { 771 if (type == Intensity || type == Contrast) {
772 r = qRed(color1); 772 r = qRed(color1);
773 g = qGreen(color1); 773 g = qGreen(color1);
774 b = qBlue(color1); 774 b = qBlue(color1);
775 if (channel != All) { 775 if (channel != All) {
776 mod = (channel == Red) ? qRed(color2) : 776 mod = (channel == Red) ? qRed(color2) :
777 (channel == Green) ? qGreen(color2) : 777 (channel == Green) ? qGreen(color2) :
778 (channel == Blue) ? qBlue(color2) : 778 (channel == Blue) ? qBlue(color2) :
779 (channel == Gray) ? qGray(color2) : 0; 779 (channel == Gray) ? qGray(color2) : 0;
780 mod = mod*factor/50; 780 mod = mod*factor/50;
781 } 781 }
782 782
783 if (type == Intensity) { 783 if (type == Intensity) {
784 if (channel == All) { 784 if (channel == All) {
785 r += r * factor/50 * qRed(color2)/256; 785 r += r * factor/50 * qRed(color2)/256;
786 g += g * factor/50 * qGreen(color2)/256; 786 g += g * factor/50 * qGreen(color2)/256;
787 b += b * factor/50 * qBlue(color2)/256; 787 b += b * factor/50 * qBlue(color2)/256;
788 } 788 }
789 else { 789 else {
790 r += r * mod/256; 790 r += r * mod/256;
791 g += g * mod/256; 791 g += g * mod/256;
792 b += b * mod/256; 792 b += b * mod/256;
793 } 793 }
794 } 794 }
795 else { // Contrast 795 else { // Contrast
796 if (channel == All) { 796 if (channel == All) {
797 r += (r-128) * factor/50 * qRed(color2)/128; 797 r += (r-128) * factor/50 * qRed(color2)/128;
798 g += (g-128) * factor/50 * qGreen(color2)/128; 798 g += (g-128) * factor/50 * qGreen(color2)/128;
799 b += (b-128) * factor/50 * qBlue(color2)/128; 799 b += (b-128) * factor/50 * qBlue(color2)/128;
800 } 800 }
801 else { 801 else {
802 r += (r-128) * mod/128; 802 r += (r-128) * mod/128;
803 g += (g-128) * mod/128; 803 g += (g-128) * mod/128;
804 b += (b-128) * mod/128; 804 b += (b-128) * mod/128;
805 } 805 }
806 } 806 }
807 807
808 if (r<0) r=0; if (r>255) r=255; 808 if (r<0) r=0; if (r>255) r=255;
809 if (g<0) g=0; if (g>255) g=255; 809 if (g<0) g=0; if (g>255) g=255;
810 if (b<0) b=0; if (b>255) b=255; 810 if (b<0) b=0; if (b>255) b=255;
811 a = qAlpha(*data1); 811 a = qAlpha(*data1);
812 *data1 = qRgba(r, g, b, a); 812 *data1 = qRgba(r, g, b, a);
813 } 813 }
814 else if (type == Saturation || type == HueShift) { 814 else if (type == Saturation || type == HueShift) {
815 clr.setRgb(color1); 815 clr.setRgb(color1);
816 clr.hsv(&h, &s, &v); 816 clr.hsv(&h, &s, &v);
817 mod = (channel == Red) ? qRed(color2) : 817 mod = (channel == Red) ? qRed(color2) :
818 (channel == Green) ? qGreen(color2) : 818 (channel == Green) ? qGreen(color2) :
819 (channel == Blue) ? qBlue(color2) : 819 (channel == Blue) ? qBlue(color2) :
820 (channel == Gray) ? qGray(color2) : 0; 820 (channel == Gray) ? qGray(color2) : 0;
821 mod = mod*factor/50; 821 mod = mod*factor/50;
822 822
823 if (type == Saturation) { 823 if (type == Saturation) {
824 s -= s * mod/256; 824 s -= s * mod/256;
825 if (s<0) s=0; if (s>255) s=255; 825 if (s<0) s=0; if (s>255) s=255;
826 } 826 }
827 else { // HueShift 827 else { // HueShift
828 h += mod; 828 h += mod;
829 while(h<0) h+=360; 829 while(h<0) h+=360;
830 h %= 360; 830 h %= 360;
831 } 831 }
832 832
833 clr.setHsv(h, s, v); 833 clr.setHsv(h, s, v);
834 a = qAlpha(*data1); 834 a = qAlpha(*data1);
835 *data1 = clr.rgb() | ((uint)(a & 0xff) << 24); 835 *data1 = clr.rgb() | ((uint)(a & 0xff) << 24);
836 } 836 }
837 data1++; data2++; data2b++; x++; 837 data1++; data2++; data2b++; x++;
838 if ( (x%x2) ==0) { data2 -= x2; data2b -= x2; } 838 if ( (x%x2) ==0) { data2 -= x2; data2b -= x2; }
839 } 839 }
840 } 840 }
841 return image; 841 return image;
842} 842}
843 843
844 844
845 845
846//====================================================================== 846//======================================================================
847// 847//
848// Blend effects 848// Blend effects
849// 849//
850//====================================================================== 850//======================================================================
851 851
852 852
853// Nice and fast direct pixel manipulation 853// Nice and fast direct pixel manipulation
854QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity) 854QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity)
855{ 855{
856 if (dst.width() <= 0 || dst.height() <= 0) 856 if (dst.width() <= 0 || dst.height() <= 0)
857 return dst; 857 return dst;
858 858
859 if (opacity < 0.0 || opacity > 1.0) { 859 if (opacity < 0.0 || opacity > 1.0) {
860 odebug << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1] " << oendl; 860 odebug << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1] " << oendl;
861 return dst; 861 return dst;
862 } 862 }
863 863
864 int depth = dst.depth(); 864 int depth = dst.depth();
865 if (depth != 32) 865 if (depth != 32)
866 dst = dst.convertDepth(32); 866 dst = dst.convertDepth(32);
867 867
868 int pixels = dst.width() * dst.height(); 868 int pixels = dst.width() * dst.height();
869 int rcol, gcol, bcol; 869 int rcol, gcol, bcol;
870 clr.rgb(&rcol, &gcol, &bcol); 870 clr.rgb(&rcol, &gcol, &bcol);
871 871
872#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 872#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
873 register unsigned char *data = (unsigned char *)dst.bits() + 1; 873 register unsigned char *data = (unsigned char *)dst.bits() + 1;
874#else // BGRA 874#else // BGRA
875 register unsigned char *data = (unsigned char *)dst.bits(); 875 register unsigned char *data = (unsigned char *)dst.bits();
876#endif 876#endif
877 877
878 for (register int i=0; i<pixels; i++) 878 for (register int i=0; i<pixels; i++)
879 { 879 {
880#ifdef WORDS_BIGENDIAN 880#ifdef WORDS_BIGENDIAN
881 *(data++) += (unsigned char)((rcol - *data) * opacity); 881 *(data++) += (unsigned char)((rcol - *data) * opacity);
882 *(data++) += (unsigned char)((gcol - *data) * opacity); 882 *(data++) += (unsigned char)((gcol - *data) * opacity);
883 *(data++) += (unsigned char)((bcol - *data) * opacity); 883 *(data++) += (unsigned char)((bcol - *data) * opacity);
884#else 884#else
885 *(data++) += (unsigned char)((bcol - *data) * opacity); 885 *(data++) += (unsigned char)((bcol - *data) * opacity);
886 *(data++) += (unsigned char)((gcol - *data) * opacity); 886 *(data++) += (unsigned char)((gcol - *data) * opacity);
887 *(data++) += (unsigned char)((rcol - *data) * opacity); 887 *(data++) += (unsigned char)((rcol - *data) * opacity);
888#endif 888#endif
889 data++; // skip alpha 889 data++; // skip alpha
890 } 890 }
891 return dst; 891 return dst;
892} 892}
893 893
894// Nice and fast direct pixel manipulation 894// Nice and fast direct pixel manipulation
895QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity) 895QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity)
896{ 896{
897 if (src.width() <= 0 || src.height() <= 0) 897 if (src.width() <= 0 || src.height() <= 0)
898 return dst; 898 return dst;
899 if (dst.width() <= 0 || dst.height() <= 0) 899 if (dst.width() <= 0 || dst.height() <= 0)
900 return dst; 900 return dst;
901 901
902 if (src.width() != dst.width() || src.height() != dst.height()) { 902 if (src.width() != dst.width() || src.height() != dst.height()) {
903 odebug << "WARNING: OImageEffect::blend : src and destination images are not the same size" << oendl; 903 odebug << "WARNING: OImageEffect::blend : src and destination images are not the same size" << oendl;
904 return dst; 904 return dst;
905 } 905 }
906 906
907 if (opacity < 0.0 || opacity > 1.0) { 907 if (opacity < 0.0 || opacity > 1.0) {
908 odebug << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]" << oendl; 908 odebug << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]" << oendl;
909 return dst; 909 return dst;
910 } 910 }
911 911
912 if (src.depth() != 32) src = src.convertDepth(32); 912 if (src.depth() != 32) src = src.convertDepth(32);
913 if (dst.depth() != 32) dst = dst.convertDepth(32); 913 if (dst.depth() != 32) dst = dst.convertDepth(32);
914 914
915 int pixels = src.width() * src.height(); 915 int pixels = src.width() * src.height();
916#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 916#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
917 register unsigned char *data1 = (unsigned char *)dst.bits() + 1; 917 register unsigned char *data1 = (unsigned char *)dst.bits() + 1;
918 register unsigned char *data2 = (unsigned char *)src.bits() + 1; 918 register unsigned char *data2 = (unsigned char *)src.bits() + 1;
919#else // BGRA 919#else // BGRA
920 register unsigned char *data1 = (unsigned char *)dst.bits(); 920 register unsigned char *data1 = (unsigned char *)dst.bits();
921 register unsigned char *data2 = (unsigned char *)src.bits(); 921 register unsigned char *data2 = (unsigned char *)src.bits();
922#endif 922#endif
923 923
924 for (register int i=0; i<pixels; i++) 924 for (register int i=0; i<pixels; i++)
925 { 925 {
926#ifdef WORDS_BIGENDIAN 926#ifdef WORDS_BIGENDIAN
927 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 927 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
928 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 928 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
929 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 929 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
930#else 930#else
931 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 931 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
932 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 932 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
933 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity); 933 *(data1++) += (unsigned char)((*(data2++) - *data1) * opacity);
934#endif 934#endif
935 data1++; // skip alpha 935 data1++; // skip alpha
936 data2++; 936 data2++;
937 } 937 }
938 938
939 return dst; 939 return dst;
940} 940}
941 941
942 942
943QImage& OImageEffect::blend(QImage &image, float initial_intensity, 943QImage& OImageEffect::blend(QImage &image, float initial_intensity,
944 const QColor &bgnd, GradientType eff, 944 const QColor &bgnd, GradientType eff,
945 bool anti_dir) 945 bool anti_dir)
946{ 946{
947 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) { 947 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) {
948 odebug << "WARNING: OImageEffect::blend : invalid image" << oendl; 948 odebug << "WARNING: OImageEffect::blend : invalid image" << oendl;
949 return image; 949 return image;
950 } 950 }
951 951
952 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); 952 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue();
953 int r, g, b; 953 int r, g, b;
954 int ind; 954 int ind;
955 955
956 unsigned int xi, xf, yi, yf; 956 unsigned int xi, xf, yi, yf;
957 unsigned int a; 957 unsigned int a;
958 958
959 // check the boundaries of the initial intesity param 959 // check the boundaries of the initial intesity param
960 float unaffected = 1; 960 float unaffected = 1;
961 if (initial_intensity > 1) initial_intensity = 1; 961 if (initial_intensity > 1) initial_intensity = 1;
962 if (initial_intensity < -1) initial_intensity = -1; 962 if (initial_intensity < -1) initial_intensity = -1;
963 if (initial_intensity < 0) { 963 if (initial_intensity < 0) {
964 unaffected = 1. + initial_intensity; 964 unaffected = 1. + initial_intensity;
965 initial_intensity = 0; 965 initial_intensity = 0;
966 } 966 }
967 967
968 968
969 float intensity = initial_intensity; 969 float intensity = initial_intensity;
970 float var = 1. - initial_intensity; 970 float var = 1. - initial_intensity;
971 971
972 if (anti_dir) { 972 if (anti_dir) {
973 initial_intensity = intensity = 1.; 973 initial_intensity = intensity = 1.;
974 var = -var; 974 var = -var;
975 } 975 }
976 976
977 register int x, y; 977 register int x, y;
978 978
979 unsigned int *data = (unsigned int *)image.bits(); 979 unsigned int *data = (unsigned int *)image.bits();
980 980
981 int image_width = image.width(); //Those can't change 981 int image_width = image.width(); //Those can't change
982 int image_height = image.height(); 982 int image_height = image.height();
983 983
984 984
985 if( eff == VerticalGradient || eff == HorizontalGradient ) { 985 if( eff == VerticalGradient || eff == HorizontalGradient ) {
986 986
987 // set the image domain to apply the effect to 987 // set the image domain to apply the effect to
988 xi = 0, xf = image_width; 988 xi = 0, xf = image_width;
989 yi = 0, yf = image_height; 989 yi = 0, yf = image_height;
990 if (eff == VerticalGradient) { 990 if (eff == VerticalGradient) {
991 if (anti_dir) yf = (int)(image_height * unaffected); 991 if (anti_dir) yf = (int)(image_height * unaffected);
992 else yi = (int)(image_height * (1 - unaffected)); 992 else yi = (int)(image_height * (1 - unaffected));
993 } 993 }
994 else { 994 else {
995 if (anti_dir) xf = (int)(image_width * unaffected); 995 if (anti_dir) xf = (int)(image_width * unaffected);
996 else xi = (int)(image_height * (1 - unaffected)); 996 else xi = (int)(image_height * (1 - unaffected));
997 } 997 }
998 998
999 var /= (eff == VerticalGradient?yf-yi:xf-xi); 999 var /= (eff == VerticalGradient?yf-yi:xf-xi);
1000 1000
1001 int ind_base; 1001 int ind_base;
1002 for (y = yi; y < (int)yf; y++) { 1002 for (y = yi; y < (int)yf; y++) {
1003 intensity = eff == VerticalGradient? intensity + var : 1003 intensity = eff == VerticalGradient? intensity + var :
1004 initial_intensity; 1004 initial_intensity;
1005 ind_base = image_width * y ; 1005 ind_base = image_width * y ;
1006 for (x = xi; x < (int)xf ; x++) { 1006 for (x = xi; x < (int)xf ; x++) {
1007 if (eff == HorizontalGradient) intensity += var; 1007 if (eff == HorizontalGradient) intensity += var;
1008 ind = x + ind_base; 1008 ind = x + ind_base;
1009 r = qRed (data[ind]) + (int)(intensity * 1009 r = qRed (data[ind]) + (int)(intensity *
1010 (r_bgnd - qRed (data[ind]))); 1010 (r_bgnd - qRed (data[ind])));
1011 g = qGreen(data[ind]) + (int)(intensity * 1011 g = qGreen(data[ind]) + (int)(intensity *
1012 (g_bgnd - qGreen(data[ind]))); 1012 (g_bgnd - qGreen(data[ind])));
1013 b = qBlue (data[ind]) + (int)(intensity * 1013 b = qBlue (data[ind]) + (int)(intensity *
1014 (b_bgnd - qBlue (data[ind]))); 1014 (b_bgnd - qBlue (data[ind])));
1015 if (r > 255) r = 255; if (r < 0 ) r = 0; 1015 if (r > 255) r = 255; if (r < 0 ) r = 0;
1016 if (g > 255) g = 255; if (g < 0 ) g = 0; 1016 if (g > 255) g = 255; if (g < 0 ) g = 0;
1017 if (b > 255) b = 255; if (b < 0 ) b = 0; 1017 if (b > 255) b = 255; if (b < 0 ) b = 0;
1018 a = qAlpha(data[ind]); 1018 a = qAlpha(data[ind]);
1019 data[ind] = qRgba(r, g, b, a); 1019 data[ind] = qRgba(r, g, b, a);
1020 } 1020 }
1021 } 1021 }
1022 } 1022 }
1023 else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) { 1023 else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) {
1024 float xvar = var / 2 / image_width; // / unaffected; 1024 float xvar = var / 2 / image_width; // / unaffected;
1025 float yvar = var / 2 / image_height; // / unaffected; 1025 float yvar = var / 2 / image_height; // / unaffected;
1026 float tmp; 1026 float tmp;
1027 1027
1028 for (x = 0; x < image_width ; x++) { 1028 for (x = 0; x < image_width ; x++) {
1029 tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1); 1029 tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1);
1030 ind = x; 1030 ind = x;
1031 for (y = 0; y < image_height ; y++) { 1031 for (y = 0; y < image_height ; y++) {
1032 intensity = initial_intensity + tmp + yvar * y; 1032 intensity = initial_intensity + tmp + yvar * y;
1033 1033
1034 r = qRed (data[ind]) + (int)(intensity * 1034 r = qRed (data[ind]) + (int)(intensity *
1035 (r_bgnd - qRed (data[ind]))); 1035 (r_bgnd - qRed (data[ind])));
1036 g = qGreen(data[ind]) + (int)(intensity * 1036 g = qGreen(data[ind]) + (int)(intensity *
1037 (g_bgnd - qGreen(data[ind]))); 1037 (g_bgnd - qGreen(data[ind])));
1038 b = qBlue (data[ind]) + (int)(intensity * 1038 b = qBlue (data[ind]) + (int)(intensity *
1039 (b_bgnd - qBlue (data[ind]))); 1039 (b_bgnd - qBlue (data[ind])));
1040 if (r > 255) r = 255; if (r < 0 ) r = 0; 1040 if (r > 255) r = 255; if (r < 0 ) r = 0;
1041 if (g > 255) g = 255; if (g < 0 ) g = 0; 1041 if (g > 255) g = 255; if (g < 0 ) g = 0;
1042 if (b > 255) b = 255; if (b < 0 ) b = 0; 1042 if (b > 255) b = 255; if (b < 0 ) b = 0;
1043 a = qAlpha(data[ind]); 1043 a = qAlpha(data[ind]);
1044 data[ind] = qRgba(r, g, b, a); 1044 data[ind] = qRgba(r, g, b, a);
1045 1045
1046 ind += image_width; 1046 ind += image_width;
1047 } 1047 }
1048 } 1048 }
1049 } 1049 }
1050 1050
1051 else if (eff == RectangleGradient || eff == EllipticGradient) { 1051 else if (eff == RectangleGradient || eff == EllipticGradient) {
1052 float xvar; 1052 float xvar;
1053 float yvar; 1053 float yvar;
1054 1054
1055 for (x = 0; x < image_width / 2 + image_width % 2; x++) { 1055 for (x = 0; x < image_width / 2 + image_width % 2; x++) {
1056 xvar = var / image_width * (image_width - x*2/unaffected-1); 1056 xvar = var / image_width * (image_width - x*2/unaffected-1);
1057 for (y = 0; y < image_height / 2 + image_height % 2; y++) { 1057 for (y = 0; y < image_height / 2 + image_height % 2; y++) {
1058 yvar = var / image_height * (image_height - y*2/unaffected -1); 1058 yvar = var / image_height * (image_height - y*2/unaffected -1);
1059 1059
1060 if (eff == RectangleGradient) 1060 if (eff == RectangleGradient)
1061 intensity = initial_intensity + QMAX(xvar, yvar); 1061 intensity = initial_intensity + QMAX(xvar, yvar);
1062 else 1062 else
1063 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); 1063 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
1064 if (intensity > 1) intensity = 1; 1064 if (intensity > 1) intensity = 1;
1065 if (intensity < 0) intensity = 0; 1065 if (intensity < 0) intensity = 0;
1066 1066
1067 //NW 1067 //NW
1068 ind = x + image_width * y ; 1068 ind = x + image_width * y ;
1069 r = qRed (data[ind]) + (int)(intensity * 1069 r = qRed (data[ind]) + (int)(intensity *
1070 (r_bgnd - qRed (data[ind]))); 1070 (r_bgnd - qRed (data[ind])));
1071 g = qGreen(data[ind]) + (int)(intensity * 1071 g = qGreen(data[ind]) + (int)(intensity *
1072 (g_bgnd - qGreen(data[ind]))); 1072 (g_bgnd - qGreen(data[ind])));
1073 b = qBlue (data[ind]) + (int)(intensity * 1073 b = qBlue (data[ind]) + (int)(intensity *
1074 (b_bgnd - qBlue (data[ind]))); 1074 (b_bgnd - qBlue (data[ind])));
1075 if (r > 255) r = 255; if (r < 0 ) r = 0; 1075 if (r > 255) r = 255; if (r < 0 ) r = 0;
1076 if (g > 255) g = 255; if (g < 0 ) g = 0; 1076 if (g > 255) g = 255; if (g < 0 ) g = 0;
1077 if (b > 255) b = 255; if (b < 0 ) b = 0; 1077 if (b > 255) b = 255; if (b < 0 ) b = 0;
1078 a = qAlpha(data[ind]); 1078 a = qAlpha(data[ind]);
1079 data[ind] = qRgba(r, g, b, a); 1079 data[ind] = qRgba(r, g, b, a);
1080 1080
1081 //NE 1081 //NE
1082 ind = image_width - x - 1 + image_width * y ; 1082 ind = image_width - x - 1 + image_width * y ;
1083 r = qRed (data[ind]) + (int)(intensity * 1083 r = qRed (data[ind]) + (int)(intensity *
1084 (r_bgnd - qRed (data[ind]))); 1084 (r_bgnd - qRed (data[ind])));
1085 g = qGreen(data[ind]) + (int)(intensity * 1085 g = qGreen(data[ind]) + (int)(intensity *
1086 (g_bgnd - qGreen(data[ind]))); 1086 (g_bgnd - qGreen(data[ind])));
1087 b = qBlue (data[ind]) + (int)(intensity * 1087 b = qBlue (data[ind]) + (int)(intensity *
1088 (b_bgnd - qBlue (data[ind]))); 1088 (b_bgnd - qBlue (data[ind])));
1089 if (r > 255) r = 255; if (r < 0 ) r = 0; 1089 if (r > 255) r = 255; if (r < 0 ) r = 0;
1090 if (g > 255) g = 255; if (g < 0 ) g = 0; 1090 if (g > 255) g = 255; if (g < 0 ) g = 0;
1091 if (b > 255) b = 255; if (b < 0 ) b = 0; 1091 if (b > 255) b = 255; if (b < 0 ) b = 0;
1092 a = qAlpha(data[ind]); 1092 a = qAlpha(data[ind]);
1093 data[ind] = qRgba(r, g, b, a); 1093 data[ind] = qRgba(r, g, b, a);
1094 } 1094 }
1095 } 1095 }
1096 1096
1097 //CT loop is doubled because of stupid central row/column issue. 1097 //CT loop is doubled because of stupid central row/column issue.
1098 // other solution? 1098 // other solution?
1099 for (x = 0; x < image_width / 2; x++) { 1099 for (x = 0; x < image_width / 2; x++) {
1100 xvar = var / image_width * (image_width - x*2/unaffected-1); 1100 xvar = var / image_width * (image_width - x*2/unaffected-1);
1101 for (y = 0; y < image_height / 2; y++) { 1101 for (y = 0; y < image_height / 2; y++) {
1102 yvar = var / image_height * (image_height - y*2/unaffected -1); 1102 yvar = var / image_height * (image_height - y*2/unaffected -1);
1103 1103
1104 if (eff == RectangleGradient) 1104 if (eff == RectangleGradient)
1105 intensity = initial_intensity + QMAX(xvar, yvar); 1105 intensity = initial_intensity + QMAX(xvar, yvar);
1106 else 1106 else
1107 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); 1107 intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar);
1108 if (intensity > 1) intensity = 1; 1108 if (intensity > 1) intensity = 1;
1109 if (intensity < 0) intensity = 0; 1109 if (intensity < 0) intensity = 0;
1110 1110
1111 //SW 1111 //SW
1112 ind = x + image_width * (image_height - y -1) ; 1112 ind = x + image_width * (image_height - y -1) ;
1113 r = qRed (data[ind]) + (int)(intensity * 1113 r = qRed (data[ind]) + (int)(intensity *
1114 (r_bgnd - qRed (data[ind]))); 1114 (r_bgnd - qRed (data[ind])));
1115 g = qGreen(data[ind]) + (int)(intensity * 1115 g = qGreen(data[ind]) + (int)(intensity *
1116 (g_bgnd - qGreen(data[ind]))); 1116 (g_bgnd - qGreen(data[ind])));
1117 b = qBlue (data[ind]) + (int)(intensity * 1117 b = qBlue (data[ind]) + (int)(intensity *
1118 (b_bgnd - qBlue (data[ind]))); 1118 (b_bgnd - qBlue (data[ind])));
1119 if (r > 255) r = 255; if (r < 0 ) r = 0; 1119 if (r > 255) r = 255; if (r < 0 ) r = 0;
1120 if (g > 255) g = 255; if (g < 0 ) g = 0; 1120 if (g > 255) g = 255; if (g < 0 ) g = 0;
1121 if (b > 255) b = 255; if (b < 0 ) b = 0; 1121 if (b > 255) b = 255; if (b < 0 ) b = 0;
1122 a = qAlpha(data[ind]); 1122 a = qAlpha(data[ind]);
1123 data[ind] = qRgba(r, g, b, a); 1123 data[ind] = qRgba(r, g, b, a);
1124 1124
1125 //SE 1125 //SE
1126 ind = image_width-x-1 + image_width * (image_height - y - 1) ; 1126 ind = image_width-x-1 + image_width * (image_height - y - 1) ;
1127 r = qRed (data[ind]) + (int)(intensity * 1127 r = qRed (data[ind]) + (int)(intensity *
1128 (r_bgnd - qRed (data[ind]))); 1128 (r_bgnd - qRed (data[ind])));
1129 g = qGreen(data[ind]) + (int)(intensity * 1129 g = qGreen(data[ind]) + (int)(intensity *
1130 (g_bgnd - qGreen(data[ind]))); 1130 (g_bgnd - qGreen(data[ind])));
1131 b = qBlue (data[ind]) + (int)(intensity * 1131 b = qBlue (data[ind]) + (int)(intensity *
1132 (b_bgnd - qBlue (data[ind]))); 1132 (b_bgnd - qBlue (data[ind])));
1133 if (r > 255) r = 255; if (r < 0 ) r = 0; 1133 if (r > 255) r = 255; if (r < 0 ) r = 0;
1134 if (g > 255) g = 255; if (g < 0 ) g = 0; 1134 if (g > 255) g = 255; if (g < 0 ) g = 0;
1135 if (b > 255) b = 255; if (b < 0 ) b = 0; 1135 if (b > 255) b = 255; if (b < 0 ) b = 0;
1136 a = qAlpha(data[ind]); 1136 a = qAlpha(data[ind]);
1137 data[ind] = qRgba(r, g, b, a); 1137 data[ind] = qRgba(r, g, b, a);
1138 } 1138 }
1139 } 1139 }
1140 } 1140 }
1141 else odebug << "OImageEffect::blend effect not implemented" << oendl; 1141 else odebug << "OImageEffect::blend effect not implemented" << oendl;
1142 return image; 1142 return image;
1143} 1143}
1144 1144
1145// Not very efficient as we create a third big image... 1145// Not very efficient as we create a third big image...
1146// 1146//
1147QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1147QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1148 GradientType gt, int xf, int yf) 1148 GradientType gt, int xf, int yf)
1149{ 1149{
1150 if (image1.width() == 0 || image1.height() == 0 || 1150 if (image1.width() == 0 || image1.height() == 0 ||
1151 image2.width() == 0 || image2.height() == 0) 1151 image2.width() == 0 || image2.height() == 0)
1152 return image1; 1152 return image1;
1153 1153
1154 QImage image3; 1154 QImage image3;
1155 1155
1156 image3 = OImageEffect::unbalancedGradient(image1.size(), 1156 image3 = OImageEffect::unbalancedGradient(image1.size(),
1157 QColor(0,0,0), QColor(255,255,255), 1157 QColor(0,0,0), QColor(255,255,255),
1158 gt, xf, yf, 0); 1158 gt, xf, yf, 0);
1159 1159
1160 return blend(image1,image2,image3, Red); // Channel to use is arbitrary 1160 return blend(image1,image2,image3, Red); // Channel to use is arbitrary
1161} 1161}
1162 1162
1163// Blend image2 into image1, using an RBG channel of blendImage 1163// Blend image2 into image1, using an RBG channel of blendImage
1164// 1164//
1165QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1165QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1166 QImage &blendImage, RGBComponent channel) 1166 QImage &blendImage, RGBComponent channel)
1167{ 1167{
1168 if (image1.width() == 0 || image1.height() == 0 || 1168 if (image1.width() == 0 || image1.height() == 0 ||
1169 image2.width() == 0 || image2.height() == 0 || 1169 image2.width() == 0 || image2.height() == 0 ||
1170 blendImage.width() == 0 || blendImage.height() == 0) { 1170 blendImage.width() == 0 || blendImage.height() == 0) {
1171 odebug << "OImageEffect::blend effect invalid image" << oendl; 1171 odebug << "OImageEffect::blend effect invalid image" << oendl;
1172 return image1; 1172 return image1;
1173 } 1173 }
1174 1174
1175 int r, g, b; 1175 int r, g, b;
1176 int ind1, ind2, ind3; 1176 int ind1, ind2, ind3;
1177 1177
1178 unsigned int x1, x2, x3, y1, y2, y3; 1178 unsigned int x1, x2, x3, y1, y2, y3;
1179 unsigned int a; 1179 unsigned int a;
1180 1180
1181 register int x, y; 1181 register int x, y;
1182 1182
1183 // for image1 and image2, we only handle depth 32 1183 // for image1 and image2, we only handle depth 32
1184 if (image1.depth()<32) image1 = image1.convertDepth(32); 1184 if (image1.depth()<32) image1 = image1.convertDepth(32);
1185 if (image2.depth()<32) image2 = image2.convertDepth(32); 1185 if (image2.depth()<32) image2 = image2.convertDepth(32);
1186 1186
1187 // for blendImage, we handle depth 8 and 32 1187 // for blendImage, we handle depth 8 and 32
1188 if (blendImage.depth()<8) blendImage = blendImage.convertDepth(8); 1188 if (blendImage.depth()<8) blendImage = blendImage.convertDepth(8);
1189 1189
1190 unsigned int *colorTable3 = (blendImage.depth()==8) ? 1190 unsigned int *colorTable3 = (blendImage.depth()==8) ?
1191 blendImage.colorTable():0; 1191 blendImage.colorTable():0;
1192 1192
1193 unsigned int *data1 = (unsigned int *)image1.bits(); 1193 unsigned int *data1 = (unsigned int *)image1.bits();
1194 unsigned int *data2 = (unsigned int *)image2.bits(); 1194 unsigned int *data2 = (unsigned int *)image2.bits();
1195 unsigned int *data3 = (unsigned int *)blendImage.bits(); 1195 unsigned int *data3 = (unsigned int *)blendImage.bits();
1196 unsigned char *data3b = (unsigned char *)blendImage.bits(); 1196 unsigned char *data3b = (unsigned char *)blendImage.bits();
1197 unsigned int color3; 1197 unsigned int color3;
1198 1198
1199 x1 = image1.width(); y1 = image1.height(); 1199 x1 = image1.width(); y1 = image1.height();
1200 x2 = image2.width(); y2 = image2.height(); 1200 x2 = image2.width(); y2 = image2.height();
1201 x3 = blendImage.width(); y3 = blendImage.height(); 1201 x3 = blendImage.width(); y3 = blendImage.height();
1202 1202
1203 for (y = 0; y < (int)y1; y++) { 1203 for (y = 0; y < (int)y1; y++) {
1204 ind1 = x1*y; 1204 ind1 = x1*y;
1205 ind2 = x2*(y%y2); 1205 ind2 = x2*(y%y2);
1206 ind3 = x3*(y%y3); 1206 ind3 = x3*(y%y3);
1207 1207
1208 x=0; 1208 x=0;
1209 while(x < (int)x1) { 1209 while(x < (int)x1) {
1210 color3 = (colorTable3) ? colorTable3[data3b[ind3]] : data3[ind3]; 1210 color3 = (colorTable3) ? colorTable3[data3b[ind3]] : data3[ind3];
1211 1211
1212 a = (channel == Red) ? qRed(color3) : 1212 a = (channel == Red) ? qRed(color3) :
1213 (channel == Green) ? qGreen(color3) : 1213 (channel == Green) ? qGreen(color3) :
1214 (channel == Blue) ? qBlue(color3) : qGray(color3); 1214 (channel == Blue) ? qBlue(color3) : qGray(color3);
1215 1215
1216 r = (a*qRed(data1[ind1]) + (256-a)*qRed(data2[ind2]))/256; 1216 r = (a*qRed(data1[ind1]) + (256-a)*qRed(data2[ind2]))/256;
1217 g = (a*qGreen(data1[ind1]) + (256-a)*qGreen(data2[ind2]))/256; 1217 g = (a*qGreen(data1[ind1]) + (256-a)*qGreen(data2[ind2]))/256;
1218 b = (a*qBlue(data1[ind1]) + (256-a)*qBlue(data2[ind2]))/256; 1218 b = (a*qBlue(data1[ind1]) + (256-a)*qBlue(data2[ind2]))/256;
1219 1219
1220 a = qAlpha(data1[ind1]); 1220 a = qAlpha(data1[ind1]);
1221 data1[ind1] = qRgba(r, g, b, a); 1221 data1[ind1] = qRgba(r, g, b, a);
1222 1222
1223 ind1++; ind2++; ind3++; x++; 1223 ind1++; ind2++; ind3++; x++;
1224 if ( (x%x2) ==0) ind2 -= x2; 1224 if ( (x%x2) ==0) ind2 -= x2;
1225 if ( (x%x3) ==0) ind3 -= x3; 1225 if ( (x%x3) ==0) ind3 -= x3;
1226 } 1226 }
1227 } 1227 }
1228 return image1; 1228 return image1;
1229} 1229}
1230 1230
1231 1231
1232//====================================================================== 1232//======================================================================
1233// 1233//
1234// Hash effects 1234// Hash effects
1235// 1235//
1236//====================================================================== 1236//======================================================================
1237 1237
1238unsigned int OImageEffect::lHash(unsigned int c) 1238unsigned int OImageEffect::lHash(unsigned int c)
1239{ 1239{
1240 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c); 1240 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c);
1241 unsigned char nr, ng, nb; 1241 unsigned char nr, ng, nb;
1242 nr =(r >> 1) + (r >> 2); nr = nr > r ? 0 : nr; 1242 nr =(r >> 1) + (r >> 2); nr = nr > r ? 0 : nr;
1243 ng =(g >> 1) + (g >> 2); ng = ng > g ? 0 : ng; 1243 ng =(g >> 1) + (g >> 2); ng = ng > g ? 0 : ng;
1244 nb =(b >> 1) + (b >> 2); nb = nb > b ? 0 : nb; 1244 nb =(b >> 1) + (b >> 2); nb = nb > b ? 0 : nb;
1245 1245
1246 return qRgba(nr, ng, nb, a); 1246 return qRgba(nr, ng, nb, a);
1247} 1247}
1248 1248
1249 1249
1250// ----------------------------------------------------------------------------- 1250// -----------------------------------------------------------------------------
1251 1251
1252unsigned int OImageEffect::uHash(unsigned int c) 1252unsigned int OImageEffect::uHash(unsigned int c)
1253{ 1253{
1254 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c); 1254 unsigned char r = qRed(c), g = qGreen(c), b = qBlue(c), a = qAlpha(c);
1255 unsigned char nr, ng, nb; 1255 unsigned char nr, ng, nb;
1256 nr = r + (r >> 3); nr = nr < r ? ~0 : nr; 1256 nr = r + (r >> 3); nr = nr < r ? ~0 : nr;
1257 ng = g + (g >> 3); ng = ng < g ? ~0 : ng; 1257 ng = g + (g >> 3); ng = ng < g ? ~0 : ng;
1258 nb = b + (b >> 3); nb = nb < b ? ~0 : nb; 1258 nb = b + (b >> 3); nb = nb < b ? ~0 : nb;
1259 1259
1260 return qRgba(nr, ng, nb, a); 1260 return qRgba(nr, ng, nb, a);
1261} 1261}
1262 1262
1263 1263
1264// ----------------------------------------------------------------------------- 1264// -----------------------------------------------------------------------------
1265 1265
1266QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing) 1266QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing)
1267{ 1267{
1268 if (image.width() == 0 || image.height() == 0) { 1268 if (image.width() == 0 || image.height() == 0) {
1269 odebug << "OImageEffect::hash effect invalid image" << oendl; 1269 odebug << "OImageEffect::hash effect invalid image" << oendl;
1270 return image; 1270 return image;
1271 } 1271 }
1272 1272
1273 register int x, y; 1273 register int x, y;
1274 unsigned int *data = (unsigned int *)image.bits(); 1274 unsigned int *data = (unsigned int *)image.bits();
1275 unsigned int ind; 1275 unsigned int ind;
1276 1276
1277 //CT no need to do it if not enough space 1277 //CT no need to do it if not enough space
1278 if ((lite == NorthLite || 1278 if ((lite == NorthLite ||
1279 lite == SouthLite)&& 1279 lite == SouthLite)&&
1280 (unsigned)image.height() < 2+spacing) return image; 1280 (unsigned)image.height() < 2+spacing) return image;
1281 if ((lite == EastLite || 1281 if ((lite == EastLite ||
1282 lite == WestLite)&& 1282 lite == WestLite)&&
1283 (unsigned)image.height() < 2+spacing) return image; 1283 (unsigned)image.height() < 2+spacing) return image;
1284 1284
1285 if (lite == NorthLite || lite == SouthLite) { 1285 if (lite == NorthLite || lite == SouthLite) {
1286 for (y = 0 ; y < image.height(); y = y + 2 + spacing) { 1286 for (y = 0 ; y < image.height(); y = y + 2 + spacing) {
1287 for (x = 0; x < image.width(); x++) { 1287 for (x = 0; x < image.width(); x++) {
1288 ind = x + image.width() * y; 1288 ind = x + image.width() * y;
1289 data[ind] = lite==NorthLite?uHash(data[ind]):lHash(data[ind]); 1289 data[ind] = lite==NorthLite?uHash(data[ind]):lHash(data[ind]);
1290 1290
1291 ind = ind + image.width(); 1291 ind = ind + image.width();
1292 data[ind] = lite==NorthLite?lHash(data[ind]):uHash(data[ind]); 1292 data[ind] = lite==NorthLite?lHash(data[ind]):uHash(data[ind]);
1293 } 1293 }
1294 } 1294 }
1295 } 1295 }
1296 1296
1297 else if (lite == EastLite || lite == WestLite) { 1297 else if (lite == EastLite || lite == WestLite) {
1298 for (y = 0 ; y < image.height(); y++) { 1298 for (y = 0 ; y < image.height(); y++) {
1299 for (x = 0; x < image.width(); x = x + 2 + spacing) { 1299 for (x = 0; x < image.width(); x = x + 2 + spacing) {
1300 ind = x + image.width() * y; 1300 ind = x + image.width() * y;
1301 data[ind] = lite==EastLite?uHash(data[ind]):lHash(data[ind]); 1301 data[ind] = lite==EastLite?uHash(data[ind]):lHash(data[ind]);
1302 1302
1303 ind++; 1303 ind++;
1304 data[ind] = lite==EastLite?lHash(data[ind]):uHash(data[ind]); 1304 data[ind] = lite==EastLite?lHash(data[ind]):uHash(data[ind]);
1305 } 1305 }
1306 } 1306 }
1307 } 1307 }
1308 1308
1309 else if (lite == NWLite || lite == SELite) { 1309 else if (lite == NWLite || lite == SELite) {
1310 for (y = 0 ; y < image.height(); y++) { 1310 for (y = 0 ; y < image.height(); y++) {
1311 for (x = 0; 1311 for (x = 0;
1312 x < (int)(image.width() - ((y & 1)? 1 : 0) * spacing); 1312 x < (int)(image.width() - ((y & 1)? 1 : 0) * spacing);
1313 x = x + 2 + spacing) { 1313 x = x + 2 + spacing) {
1314 ind = x + image.width() * y + ((y & 1)? 1 : 0); 1314 ind = x + image.width() * y + ((y & 1)? 1 : 0);
1315 data[ind] = lite==NWLite?uHash(data[ind]):lHash(data[ind]); 1315 data[ind] = lite==NWLite?uHash(data[ind]):lHash(data[ind]);
1316 1316
1317 ind++; 1317 ind++;
1318 data[ind] = lite==NWLite?lHash(data[ind]):uHash(data[ind]); 1318 data[ind] = lite==NWLite?lHash(data[ind]):uHash(data[ind]);
1319 } 1319 }
1320 } 1320 }
1321 } 1321 }
1322 1322
1323 else if (lite == SWLite || lite == NELite) { 1323 else if (lite == SWLite || lite == NELite) {
1324 for (y = 0 ; y < image.height(); y++) { 1324 for (y = 0 ; y < image.height(); y++) {
1325 for (x = 0 + ((y & 1)? 1 : 0); x < image.width(); x = x + 2 + spacing) { 1325 for (x = 0 + ((y & 1)? 1 : 0); x < image.width(); x = x + 2 + spacing) {
1326 ind = x + image.width() * y - ((y & 1)? 1 : 0); 1326 ind = x + image.width() * y - ((y & 1)? 1 : 0);
1327 data[ind] = lite==SWLite?uHash(data[ind]):lHash(data[ind]); 1327 data[ind] = lite==SWLite?uHash(data[ind]):lHash(data[ind]);
1328 1328
1329 ind++; 1329 ind++;
1330 data[ind] = lite==SWLite?lHash(data[ind]):uHash(data[ind]); 1330 data[ind] = lite==SWLite?lHash(data[ind]):uHash(data[ind]);
1331 } 1331 }
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 return image; 1335 return image;
1336} 1336}
1337 1337
1338 1338
1339//====================================================================== 1339//======================================================================
1340// 1340//
1341// Flatten effects 1341// Flatten effects
1342// 1342//
1343//====================================================================== 1343//======================================================================
1344 1344
1345QImage& OImageEffect::flatten(QImage &img, const QColor &ca, 1345QImage& OImageEffect::flatten(QImage &img, const QColor &ca,
1346 const QColor &cb, int ncols) 1346 const QColor &cb, int ncols)
1347{ 1347{
1348 if (img.width() == 0 || img.height() == 0) 1348 if (img.width() == 0 || img.height() == 0)
1349 return img; 1349 return img;
1350 1350
1351 // a bitmap is easy... 1351 // a bitmap is easy...
1352 if (img.depth() == 1) { 1352 if (img.depth() == 1) {
1353 img.setColor(0, ca.rgb()); 1353 img.setColor(0, ca.rgb());
1354 img.setColor(1, cb.rgb()); 1354 img.setColor(1, cb.rgb());
1355 return img; 1355 return img;
1356 } 1356 }
1357 1357
1358 int r1 = ca.red(); int r2 = cb.red(); 1358 int r1 = ca.red(); int r2 = cb.red();
1359 int g1 = ca.green(); int g2 = cb.green(); 1359 int g1 = ca.green(); int g2 = cb.green();
1360 int b1 = ca.blue(); int b2 = cb.blue(); 1360 int b1 = ca.blue(); int b2 = cb.blue();
1361 int min = 0, max = 255; 1361 int min = 0, max = 255;
1362 1362
1363 QRgb col; 1363 QRgb col;
1364 1364
1365 // Get minimum and maximum greylevel. 1365 // Get minimum and maximum greylevel.
1366 if (img.numColors()) { 1366 if (img.numColors()) {
1367 // pseudocolor 1367 // pseudocolor
1368 for (int i = 0; i < img.numColors(); i++) { 1368 for (int i = 0; i < img.numColors(); i++) {
1369 col = img.color(i); 1369 col = img.color(i);
1370 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1370 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1371 min = QMIN(min, mean); 1371 min = QMIN(min, mean);
1372 max = QMAX(max, mean); 1372 max = QMAX(max, mean);
1373 } 1373 }
1374 } else { 1374 } else {
1375 // truecolor 1375 // truecolor
1376 for (int y=0; y < img.height(); y++) 1376 for (int y=0; y < img.height(); y++)
1377 for (int x=0; x < img.width(); x++) { 1377 for (int x=0; x < img.width(); x++) {
1378 col = img.pixel(x, y); 1378 col = img.pixel(x, y);
1379 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1379 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1380 min = QMIN(min, mean); 1380 min = QMIN(min, mean);
1381 max = QMAX(max, mean); 1381 max = QMAX(max, mean);
1382 } 1382 }
1383 } 1383 }
1384 1384
1385 // Conversion factors 1385 // Conversion factors
1386 float sr = ((float) r2 - r1) / (max - min); 1386 float sr = ((float) r2 - r1) / (max - min);
1387 float sg = ((float) g2 - g1) / (max - min); 1387 float sg = ((float) g2 - g1) / (max - min);
1388 float sb = ((float) b2 - b1) / (max - min); 1388 float sb = ((float) b2 - b1) / (max - min);
1389 1389
1390 1390
1391 // Repaint the image 1391 // Repaint the image
1392 if (img.numColors()) { 1392 if (img.numColors()) {
1393 for (int i=0; i < img.numColors(); i++) { 1393 for (int i=0; i < img.numColors(); i++) {
1394 col = img.color(i); 1394 col = img.color(i);
1395 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1395 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1396 int r = (int) (sr * (mean - min) + r1 + 0.5); 1396 int r = (int) (sr * (mean - min) + r1 + 0.5);
1397 int g = (int) (sg * (mean - min) + g1 + 0.5); 1397 int g = (int) (sg * (mean - min) + g1 + 0.5);
1398 int b = (int) (sb * (mean - min) + b1 + 0.5); 1398 int b = (int) (sb * (mean - min) + b1 + 0.5);
1399 img.setColor(i, qRgba(r, g, b, qAlpha(col))); 1399 img.setColor(i, qRgba(r, g, b, qAlpha(col)));
1400 } 1400 }
1401 } else { 1401 } else {
1402 for (int y=0; y < img.height(); y++) 1402 for (int y=0; y < img.height(); y++)
1403 for (int x=0; x < img.width(); x++) { 1403 for (int x=0; x < img.width(); x++) {
1404 col = img.pixel(x, y); 1404 col = img.pixel(x, y);
1405 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3; 1405 int mean = (qRed(col) + qGreen(col) + qBlue(col)) / 3;
1406 int r = (int) (sr * (mean - min) + r1 + 0.5); 1406 int r = (int) (sr * (mean - min) + r1 + 0.5);
1407 int g = (int) (sg * (mean - min) + g1 + 0.5); 1407 int g = (int) (sg * (mean - min) + g1 + 0.5);
1408 int b = (int) (sb * (mean - min) + b1 + 0.5); 1408 int b = (int) (sb * (mean - min) + b1 + 0.5);
1409 img.setPixel(x, y, qRgba(r, g, b, qAlpha(col))); 1409 img.setPixel(x, y, qRgba(r, g, b, qAlpha(col)));
1410 } 1410 }
1411 } 1411 }
1412 1412
1413 1413
1414 // Dither if necessary 1414 // Dither if necessary
1415 if ( (ncols <= 0) || ((img.numColors() != 0) && (img.numColors() <= ncols))) 1415 if ( (ncols <= 0) || ((img.numColors() != 0) && (img.numColors() <= ncols)))
1416 return img; 1416 return img;
1417 1417
1418 if (ncols == 1) ncols++; 1418 if (ncols == 1) ncols++;
1419 if (ncols > 256) ncols = 256; 1419 if (ncols > 256) ncols = 256;
1420 1420
1421 QColor *pal = new QColor[ncols]; 1421 QColor *pal = new QColor[ncols];
1422 sr = ((float) r2 - r1) / (ncols - 1); 1422 sr = ((float) r2 - r1) / (ncols - 1);
1423 sg = ((float) g2 - g1) / (ncols - 1); 1423 sg = ((float) g2 - g1) / (ncols - 1);
1424 sb = ((float) b2 - b1) / (ncols - 1); 1424 sb = ((float) b2 - b1) / (ncols - 1);
1425 1425
1426 for (int i=0; i<ncols; i++) 1426 for (int i=0; i<ncols; i++)
1427 pal[i] = QColor(r1 + int(sr*i), g1 + int(sg*i), b1 + int(sb*i)); 1427 pal[i] = QColor(r1 + int(sr*i), g1 + int(sg*i), b1 + int(sb*i));
1428 1428
1429 dither(img, pal, ncols); 1429 dither(img, pal, ncols);
1430 1430
1431 delete[] pal; 1431 delete[] pal;
1432 return img; 1432 return img;
1433} 1433}
1434 1434
1435 1435
1436//====================================================================== 1436//======================================================================
1437// 1437//
1438// Fade effects 1438// Fade effects
1439// 1439//
1440//====================================================================== 1440//======================================================================
1441 1441
1442QImage& OImageEffect::fade(QImage &img, float val, const QColor &color) 1442QImage& OImageEffect::fade(QImage &img, float val, const QColor &color)
1443{ 1443{
1444 if (img.width() == 0 || img.height() == 0) 1444 if (img.width() == 0 || img.height() == 0)
1445 return img; 1445 return img;
1446 1446
1447 // We don't handle bitmaps 1447 // We don't handle bitmaps
1448 if (img.depth() == 1) 1448 if (img.depth() == 1)
1449 return img; 1449 return img;
1450 1450
1451 unsigned char tbl[256]; 1451 unsigned char tbl[256];
1452 for (int i=0; i<256; i++) 1452 for (int i=0; i<256; i++)
1453 tbl[i] = (int) (val * i + 0.5); 1453 tbl[i] = (int) (val * i + 0.5);
1454 1454
1455 int red = color.red(); 1455 int red = color.red();
1456 int green = color.green(); 1456 int green = color.green();
1457 int blue = color.blue(); 1457 int blue = color.blue();
1458 1458
1459 QRgb col; 1459 QRgb col;
1460 int r, g, b, cr, cg, cb; 1460 int r, g, b, cr, cg, cb;
1461 1461
1462 if (img.depth() <= 8) { 1462 if (img.depth() <= 8) {
1463 // pseudo color 1463 // pseudo color
1464 for (int i=0; i<img.numColors(); i++) { 1464 for (int i=0; i<img.numColors(); i++) {
1465 col = img.color(i); 1465 col = img.color(i);
1466 cr = qRed(col); cg = qGreen(col); cb = qBlue(col); 1466 cr = qRed(col); cg = qGreen(col); cb = qBlue(col);
1467 if (cr > red) 1467 if (cr > red)
1468 r = cr - tbl[cr - red]; 1468 r = cr - tbl[cr - red];
1469 else 1469 else
1470 r = cr + tbl[red - cr]; 1470 r = cr + tbl[red - cr];
1471 if (cg > green) 1471 if (cg > green)
1472 g = cg - tbl[cg - green]; 1472 g = cg - tbl[cg - green];
1473 else 1473 else
1474 g = cg + tbl[green - cg]; 1474 g = cg + tbl[green - cg];
1475 if (cb > blue) 1475 if (cb > blue)
1476 b = cb - tbl[cb - blue]; 1476 b = cb - tbl[cb - blue];
1477 else 1477 else
1478 b = cb + tbl[blue - cb]; 1478 b = cb + tbl[blue - cb];
1479 img.setColor(i, qRgba(r, g, b, qAlpha(col))); 1479 img.setColor(i, qRgba(r, g, b, qAlpha(col)));
1480 } 1480 }
1481 1481
1482 } else { 1482 } else {
1483 // truecolor 1483 // truecolor
1484 for (int y=0; y<img.height(); y++) { 1484 for (int y=0; y<img.height(); y++) {
1485 QRgb *data = (QRgb *) img.scanLine(y); 1485 QRgb *data = (QRgb *) img.scanLine(y);
1486 for (int x=0; x<img.width(); x++) { 1486 for (int x=0; x<img.width(); x++) {
1487 col = *data; 1487 col = *data;
1488 cr = qRed(col); cg = qGreen(col); cb = qBlue(col); 1488 cr = qRed(col); cg = qGreen(col); cb = qBlue(col);
1489 if (cr > red) 1489 if (cr > red)
1490 r = cr - tbl[cr - red]; 1490 r = cr - tbl[cr - red];
1491 else 1491 else
1492 r = cr + tbl[red - cr]; 1492 r = cr + tbl[red - cr];
1493 if (cg > green) 1493 if (cg > green)
1494 g = cg - tbl[cg - green]; 1494 g = cg - tbl[cg - green];
1495 else 1495 else
1496 g = cg + tbl[green - cg]; 1496 g = cg + tbl[green - cg];
1497 if (cb > blue) 1497 if (cb > blue)
1498 b = cb - tbl[cb - blue]; 1498 b = cb - tbl[cb - blue];
1499 else 1499 else
1500 b = cb + tbl[blue - cb]; 1500 b = cb + tbl[blue - cb];
1501 *data++ = qRgba(r, g, b, qAlpha(col)); 1501 *data++ = qRgba(r, g, b, qAlpha(col));
1502 } 1502 }
1503 } 1503 }
1504 } 1504 }
1505 1505
1506 return img; 1506 return img;
1507} 1507}
1508 1508
1509//====================================================================== 1509//======================================================================
1510// 1510//
1511// Color effects 1511// Color effects
1512// 1512//
1513//====================================================================== 1513//======================================================================
1514 1514
1515// This code is adapted from code (C) Rik Hemsley <rik@kde.org> 1515// This code is adapted from code (C) Rik Hemsley <rik@kde.org>
1516// 1516//
1517// The formula used (r + b + g) /3 is different from the qGray formula 1517// The formula used (r + b + g) /3 is different from the qGray formula
1518// used by Qt. This is because our formula is much much faster. If, 1518// used by Qt. This is because our formula is much much faster. If,
1519// however, it turns out that this is producing sub-optimal images, 1519// however, it turns out that this is producing sub-optimal images,
1520// then it will have to change (kurt) 1520// then it will have to change (kurt)
1521// 1521//
1522// It does produce lower quality grayscale ;-) Use fast == true for the fast 1522// It does produce lower quality grayscale ;-) Use fast == true for the fast
1523// algorithm, false for the higher quality one (mosfet). 1523// algorithm, false for the higher quality one (mosfet).
1524QImage& OImageEffect::toGray(QImage &img, bool fast) 1524QImage& OImageEffect::toGray(QImage &img, bool fast)
1525{ 1525{
1526 if (img.width() == 0 || img.height() == 0) 1526 if (img.width() == 0 || img.height() == 0)
1527 return img; 1527 return img;
1528 1528
1529 if(fast){ 1529 if(fast){
1530 if (img.depth() == 32) { 1530 if (img.depth() == 32) {
1531 register uchar * r(img.bits()); 1531 register uchar * r(img.bits());
1532 register uchar * g(img.bits() + 1); 1532 register uchar * g(img.bits() + 1);
1533 register uchar * b(img.bits() + 2); 1533 register uchar * b(img.bits() + 2);
1534 1534
1535 uchar * end(img.bits() + img.numBytes()); 1535 uchar * end(img.bits() + img.numBytes());
1536 1536
1537 while (r != end) { 1537 while (r != end) {
1538 1538
1539 *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3 1539 *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3
1540 1540
1541 r += 4; 1541 r += 4;
1542 g += 4; 1542 g += 4;
1543 b += 4; 1543 b += 4;
1544 } 1544 }
1545 } 1545 }
1546 else 1546 else
1547 { 1547 {
1548 for (int i = 0; i < img.numColors(); i++) 1548 for (int i = 0; i < img.numColors(); i++)
1549 { 1549 {
1550 register uint r = qRed(img.color(i)); 1550 register uint r = qRed(img.color(i));
1551 register uint g = qGreen(img.color(i)); 1551 register uint g = qGreen(img.color(i));
1552 register uint b = qBlue(img.color(i)); 1552 register uint b = qBlue(img.color(i));
1553 1553
1554 register uint gray = (((r + g) >> 1) + b) >> 1; 1554 register uint gray = (((r + g) >> 1) + b) >> 1;
1555 img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i)))); 1555 img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i))));
1556 } 1556 }
1557 } 1557 }
1558 } 1558 }
1559 else{ 1559 else{
1560 int pixels = img.depth() > 8 ? img.width()*img.height() : 1560 int pixels = img.depth() > 8 ? img.width()*img.height() :
1561 img.numColors(); 1561 img.numColors();
1562 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : 1562 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() :
1563 (unsigned int *)img.colorTable(); 1563 (unsigned int *)img.colorTable();
1564 int val, i; 1564 int val, i;
1565 for(i=0; i < pixels; ++i){ 1565 for(i=0; i < pixels; ++i){
1566 val = qGray(data[i]); 1566 val = qGray(data[i]);
1567 data[i] = qRgba(val, val, val, qAlpha(data[i])); 1567 data[i] = qRgba(val, val, val, qAlpha(data[i]));
1568 } 1568 }
1569 } 1569 }
1570 return img; 1570 return img;
1571} 1571}
1572 1572
1573// CT 29Jan2000 - desaturation algorithms 1573// CT 29Jan2000 - desaturation algorithms
1574QImage& OImageEffect::desaturate(QImage &img, float desat) 1574QImage& OImageEffect::desaturate(QImage &img, float desat)
1575{ 1575{
1576 if (img.width() == 0 || img.height() == 0) 1576 if (img.width() == 0 || img.height() == 0)
1577 return img; 1577 return img;
1578 1578
1579 if (desat < 0) desat = 0.; 1579 if (desat < 0) desat = 0.;
1580 if (desat > 1) desat = 1.; 1580 if (desat > 1) desat = 1.;
1581 int pixels = img.depth() > 8 ? img.width()*img.height() : 1581 int pixels = img.depth() > 8 ? img.width()*img.height() :
1582 img.numColors(); 1582 img.numColors();
1583 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : 1583 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() :
1584 (unsigned int *)img.colorTable(); 1584 (unsigned int *)img.colorTable();
1585 int h, s, v, i; 1585 int h, s, v, i;
1586 QColor clr; // keep constructor out of loop (mosfet) 1586 QColor clr; // keep constructor out of loop (mosfet)
1587 for(i=0; i < pixels; ++i){ 1587 for(i=0; i < pixels; ++i){
1588 clr.setRgb(data[i]); 1588 clr.setRgb(data[i]);
1589 clr.hsv(&h, &s, &v); 1589 clr.hsv(&h, &s, &v);
1590 clr.setHsv(h, (int)(s * (1. - desat)), v); 1590 clr.setHsv(h, (int)(s * (1. - desat)), v);
1591 data[i] = clr.rgb(); 1591 data[i] = clr.rgb();
1592 } 1592 }
1593 return img; 1593 return img;
1594} 1594}
1595 1595
1596// Contrast stuff (mosfet) 1596// Contrast stuff (mosfet)
1597QImage& OImageEffect::contrast(QImage &img, int c) 1597QImage& OImageEffect::contrast(QImage &img, int c)
1598{ 1598{
1599 if (img.width() == 0 || img.height() == 0) 1599 if (img.width() == 0 || img.height() == 0)
1600 return img; 1600 return img;
1601 1601
1602 if(c > 255) 1602 if(c > 255)
1603 c = 255; 1603 c = 255;
1604 if(c < -255) 1604 if(c < -255)
1605 c = -255; 1605 c = -255;
1606 int pixels = img.depth() > 8 ? img.width()*img.height() : 1606 int pixels = img.depth() > 8 ? img.width()*img.height() :
1607 img.numColors(); 1607 img.numColors();
1608 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : 1608 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() :
1609 (unsigned int *)img.colorTable(); 1609 (unsigned int *)img.colorTable();
1610 int i, r, g, b; 1610 int i, r, g, b;
1611 for(i=0; i < pixels; ++i){ 1611 for(i=0; i < pixels; ++i){
1612 r = qRed(data[i]); 1612 r = qRed(data[i]);
1613 g = qGreen(data[i]); 1613 g = qGreen(data[i]);
1614 b = qBlue(data[i]); 1614 b = qBlue(data[i]);
1615 if(qGray(data[i]) <= 127){ 1615 if(qGray(data[i]) <= 127){
1616 if(r - c <= 255) 1616 if(r - c <= 255)
1617 r -= c; 1617 r -= c;
1618 if(g - c <= 255) 1618 if(g - c <= 255)
1619 g -= c; 1619 g -= c;
1620 if(b - c <= 255) 1620 if(b - c <= 255)
1621 b -= c; 1621 b -= c;
1622 } 1622 }
1623 else{ 1623 else{
1624 if(r + c <= 255) 1624 if(r + c <= 255)
1625 r += c; 1625 r += c;
1626 if(g + c <= 255) 1626 if(g + c <= 255)
1627 g += c; 1627 g += c;
1628 if(b + c <= 255) 1628 if(b + c <= 255)
1629 b += c; 1629 b += c;
1630 } 1630 }
1631 data[i] = qRgba(r, g, b, qAlpha(data[i])); 1631 data[i] = qRgba(r, g, b, qAlpha(data[i]));
1632 } 1632 }
1633 return(img); 1633 return(img);
1634} 1634}
1635 1635
1636//====================================================================== 1636//======================================================================
1637// 1637//
1638// Dithering effects 1638// Dithering effects
1639// 1639//
1640//====================================================================== 1640//======================================================================
1641 1641
1642// adapted from kFSDither (C) 1997 Martin Jones (mjones@kde.org) 1642// adapted from kFSDither (C) 1997 Martin Jones (mjones@kde.org)
1643// 1643//
1644// Floyd-Steinberg dithering 1644// Floyd-Steinberg dithering
1645// Ref: Bitmapped Graphics Programming in C++ 1645// Ref: Bitmapped Graphics Programming in C++
1646// Marv Luse, Addison-Wesley Publishing, 1993. 1646// Marv Luse, Addison-Wesley Publishing, 1993.
1647QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size) 1647QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size)
1648{ 1648{
1649 if (img.width() == 0 || img.height() == 0 || 1649 if (img.width() == 0 || img.height() == 0 ||
1650 palette == 0 || img.depth() <= 8) 1650 palette == 0 || img.depth() <= 8)
1651 return img; 1651 return img;
1652 1652
1653 QImage dImage( img.width(), img.height(), 8, size ); 1653 QImage dImage( img.width(), img.height(), 8, size );
1654 int i; 1654 int i;
1655 1655
1656 dImage.setNumColors( size ); 1656 dImage.setNumColors( size );
1657 for ( i = 0; i < size; i++ ) 1657 for ( i = 0; i < size; i++ )
1658 dImage.setColor( i, palette[ i ].rgb() ); 1658 dImage.setColor( i, palette[ i ].rgb() );
1659 1659
1660 int *rerr1 = new int [ img.width() * 2 ]; 1660 int *rerr1 = new int [ img.width() * 2 ];
1661 int *gerr1 = new int [ img.width() * 2 ]; 1661 int *gerr1 = new int [ img.width() * 2 ];
1662 int *berr1 = new int [ img.width() * 2 ]; 1662 int *berr1 = new int [ img.width() * 2 ];
1663 1663
1664 memset( rerr1, 0, sizeof( int ) * img.width() * 2 ); 1664 memset( rerr1, 0, sizeof( int ) * img.width() * 2 );
1665 memset( gerr1, 0, sizeof( int ) * img.width() * 2 ); 1665 memset( gerr1, 0, sizeof( int ) * img.width() * 2 );
1666 memset( berr1, 0, sizeof( int ) * img.width() * 2 ); 1666 memset( berr1, 0, sizeof( int ) * img.width() * 2 );
1667 1667
1668 int *rerr2 = rerr1 + img.width(); 1668 int *rerr2 = rerr1 + img.width();
1669 int *gerr2 = gerr1 + img.width(); 1669 int *gerr2 = gerr1 + img.width();
1670 int *berr2 = berr1 + img.width(); 1670 int *berr2 = berr1 + img.width();
1671 1671
1672 for ( int j = 0; j < img.height(); j++ ) 1672 for ( int j = 0; j < img.height(); j++ )
1673 { 1673 {
1674 uint *ip = (uint * )img.scanLine( j ); 1674 uint *ip = (uint * )img.scanLine( j );
1675 uchar *dp = dImage.scanLine( j ); 1675 uchar *dp = dImage.scanLine( j );
1676 1676
1677 for ( i = 0; i < img.width(); i++ ) 1677 for ( i = 0; i < img.width(); i++ )
1678 { 1678 {
1679 rerr1[i] = rerr2[i] + qRed( *ip ); 1679 rerr1[i] = rerr2[i] + qRed( *ip );
1680 rerr2[i] = 0; 1680 rerr2[i] = 0;
1681 gerr1[i] = gerr2[i] + qGreen( *ip ); 1681 gerr1[i] = gerr2[i] + qGreen( *ip );
1682 gerr2[i] = 0; 1682 gerr2[i] = 0;
1683 berr1[i] = berr2[i] + qBlue( *ip ); 1683 berr1[i] = berr2[i] + qBlue( *ip );
1684 berr2[i] = 0; 1684 berr2[i] = 0;
1685 ip++; 1685 ip++;
1686 } 1686 }
1687 1687
1688 *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); 1688 *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size );
1689 1689
1690 for ( i = 1; i < img.width()-1; i++ ) 1690 for ( i = 1; i < img.width()-1; i++ )
1691 { 1691 {
1692 int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); 1692 int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size );
1693 *dp = indx; 1693 *dp = indx;
1694 1694
1695 int rerr = rerr1[i]; 1695 int rerr = rerr1[i];
1696 rerr -= palette[indx].red(); 1696 rerr -= palette[indx].red();
1697 int gerr = gerr1[i]; 1697 int gerr = gerr1[i];
1698 gerr -= palette[indx].green(); 1698 gerr -= palette[indx].green();
1699 int berr = berr1[i]; 1699 int berr = berr1[i];
1700 berr -= palette[indx].blue(); 1700 berr -= palette[indx].blue();
1701 1701
1702 // diffuse red error 1702 // diffuse red error
1703 rerr1[ i+1 ] += ( rerr * 7 ) >> 4; 1703 rerr1[ i+1 ] += ( rerr * 7 ) >> 4;
1704 rerr2[ i-1 ] += ( rerr * 3 ) >> 4; 1704 rerr2[ i-1 ] += ( rerr * 3 ) >> 4;
1705 rerr2[ i ] += ( rerr * 5 ) >> 4; 1705 rerr2[ i ] += ( rerr * 5 ) >> 4;
1706 rerr2[ i+1 ] += ( rerr ) >> 4; 1706 rerr2[ i+1 ] += ( rerr ) >> 4;
1707 1707
1708 // diffuse green error 1708 // diffuse green error
1709 gerr1[ i+1 ] += ( gerr * 7 ) >> 4; 1709 gerr1[ i+1 ] += ( gerr * 7 ) >> 4;
1710 gerr2[ i-1 ] += ( gerr * 3 ) >> 4; 1710 gerr2[ i-1 ] += ( gerr * 3 ) >> 4;
1711 gerr2[ i ] += ( gerr * 5 ) >> 4; 1711 gerr2[ i ] += ( gerr * 5 ) >> 4;
1712 gerr2[ i+1 ] += ( gerr ) >> 4; 1712 gerr2[ i+1 ] += ( gerr ) >> 4;
1713 1713
1714 // diffuse red error 1714 // diffuse red error
1715 berr1[ i+1 ] += ( berr * 7 ) >> 4; 1715 berr1[ i+1 ] += ( berr * 7 ) >> 4;
1716 berr2[ i-1 ] += ( berr * 3 ) >> 4; 1716 berr2[ i-1 ] += ( berr * 3 ) >> 4;
1717 berr2[ i ] += ( berr * 5 ) >> 4; 1717 berr2[ i ] += ( berr * 5 ) >> 4;
1718 berr2[ i+1 ] += ( berr ) >> 4; 1718 berr2[ i+1 ] += ( berr ) >> 4;
1719 1719
1720 dp++; 1720 dp++;
1721 } 1721 }
1722 1722
1723 *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); 1723 *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size );
1724 } 1724 }
1725 1725
1726 delete [] rerr1; 1726 delete [] rerr1;
1727 delete [] gerr1; 1727 delete [] gerr1;
1728 delete [] berr1; 1728 delete [] berr1;
1729 1729
1730 img = dImage; 1730 img = dImage;
1731 return img; 1731 return img;
1732} 1732}
1733 1733
1734int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) 1734int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size )
1735{ 1735{
1736 if (palette == 0) 1736 if (palette == 0)
1737 return 0; 1737 return 0;
1738 1738
1739 int dr = palette[0].red() - r; 1739 int dr = palette[0].red() - r;
1740 int dg = palette[0].green() - g; 1740 int dg = palette[0].green() - g;
1741 int db = palette[0].blue() - b; 1741 int db = palette[0].blue() - b;
1742 1742
1743 int minDist = dr*dr + dg*dg + db*db; 1743 int minDist = dr*dr + dg*dg + db*db;
1744 int nearest = 0; 1744 int nearest = 0;
1745 1745
1746 for (int i = 1; i < size; i++ ) 1746 for (int i = 1; i < size; i++ )
1747 { 1747 {
1748 dr = palette[i].red() - r; 1748 dr = palette[i].red() - r;
1749 dg = palette[i].green() - g; 1749 dg = palette[i].green() - g;
1750 db = palette[i].blue() - b; 1750 db = palette[i].blue() - b;
1751 1751
1752 int dist = dr*dr + dg*dg + db*db; 1752 int dist = dr*dr + dg*dg + db*db;
1753 1753
1754 if ( dist < minDist ) 1754 if ( dist < minDist )
1755 { 1755 {
1756 minDist = dist; 1756 minDist = dist;
1757 nearest = i; 1757 nearest = i;
1758 } 1758 }
1759 } 1759 }
1760 1760
1761 return nearest; 1761 return nearest;
1762} 1762}
1763 1763
1764bool OImageEffect::blend( 1764bool OImageEffect::blend(
1765 const QImage & upper, 1765 const QImage & upper,
1766 const QImage & lower, 1766 const QImage & lower,
1767 QImage & output 1767 QImage & output
1768) 1768)
1769{ 1769{
1770 if ( 1770 if (
1771 upper.width() > lower.width() || 1771 upper.width() > lower.width() ||
1772 upper.height() > lower.height() || 1772 upper.height() > lower.height() ||
1773 upper.depth() != 32 || 1773 upper.depth() != 32 ||
1774 lower.depth() != 32 1774 lower.depth() != 32
1775 ) 1775 )
1776 { 1776 {
1777 odebug << "OImageEffect::blend : Sizes not correct" << oendl; 1777 odebug << "OImageEffect::blend : Sizes not correct" << oendl;
1778 return false; 1778 return false;
1779 } 1779 }
1780 1780
1781 output = lower.copy(); 1781 output = lower.copy();
1782 1782
1783 register uchar *i, *o; 1783 register uchar *i, *o;
1784 register int a; 1784 register int a;
1785 register int col; 1785 register int col;
1786 register int w = upper.width(); 1786 register int w = upper.width();
1787 int row(upper.height() - 1); 1787 int row(upper.height() - 1);
1788 1788
1789 do { 1789 do {
1790 1790
1791 i = upper.scanLine(row); 1791 i = upper.scanLine(row);
1792 o = output.scanLine(row); 1792 o = output.scanLine(row);
1793 1793
1794 col = w << 2; 1794 col = w << 2;
1795 --col; 1795 --col;
1796 1796
1797 do { 1797 do {
1798 1798
1799 while (!(a = i[col]) && (col != 3)) { 1799 while (!(a = i[col]) && (col != 3)) {
1800 --col; --col; --col; --col; 1800 --col; --col; --col; --col;
1801 } 1801 }
1802 1802
1803 --col; 1803 --col;
1804 o[col] += ((i[col] - o[col]) * a) >> 8; 1804 o[col] += ((i[col] - o[col]) * a) >> 8;
1805 1805
1806 --col; 1806 --col;
1807 o[col] += ((i[col] - o[col]) * a) >> 8; 1807 o[col] += ((i[col] - o[col]) * a) >> 8;
1808 1808
1809 --col; 1809 --col;
1810 o[col] += ((i[col] - o[col]) * a) >> 8; 1810 o[col] += ((i[col] - o[col]) * a) >> 8;
1811 1811
1812 } while (col--); 1812 } while (col--);
1813 1813
1814 } while (row--); 1814 } while (row--);
1815 1815
1816 return true; 1816 return true;
1817} 1817}
1818 1818
1819#if 0 1819#if 0
1820// Not yet... 1820// Not yet...
1821bool OImageEffect::blend( 1821bool OImageEffect::blend(
1822 const QImage & upper, 1822 const QImage & upper,
1823 const QImage & lower, 1823 const QImage & lower,
1824 QImage & output, 1824 QImage & output,
1825 const QRect & destRect 1825 const QRect & destRect
1826) 1826)
1827{ 1827{
1828 output = lower.copy(); 1828 output = lower.copy();
1829 return output; 1829 return output;
1830} 1830}
1831 1831
1832#endif 1832#endif
1833 1833
1834bool OImageEffect::blend( 1834bool OImageEffect::blend(
1835 int &x, int &y, 1835 int &x, int &y,
1836 const QImage & upper, 1836 const QImage & upper,
1837 const QImage & lower, 1837 const QImage & lower,
1838 QImage & output 1838 QImage & output
1839) 1839)
1840{ 1840{
1841 int cx=0, cy=0, cw=upper.width(), ch=upper.height(); 1841 int cx=0, cy=0, cw=upper.width(), ch=upper.height();
1842 1842
1843 if ( upper.width() + x > lower.width() || 1843 if ( upper.width() + x > lower.width() ||
1844 upper.height() + y > lower.height() || 1844 upper.height() + y > lower.height() ||
1845 x < 0 || y < 0 || 1845 x < 0 || y < 0 ||
1846 upper.depth() != 32 || lower.depth() != 32 ) 1846 upper.depth() != 32 || lower.depth() != 32 )
1847 { 1847 {
1848 if ( x > lower.width() || y > lower.height() ) return false; 1848 if ( x > lower.width() || y > lower.height() ) return false;
1849 if ( upper.width()<=0 || upper.height() <= 0 ) return false; 1849 if ( upper.width()<=0 || upper.height() <= 0 ) return false;
1850 if ( lower.width()<=0 || lower.height() <= 0 ) return false; 1850 if ( lower.width()<=0 || lower.height() <= 0 ) return false;
1851 1851
1852 if (x<0) {cx=-x; cw+=x; x=0; }; 1852 if (x<0) {cx=-x; cw+=x; x=0; };
1853 if (cw + x > lower.width()) { cw=lower.width()-x; }; 1853 if (cw + x > lower.width()) { cw=lower.width()-x; };
1854 if (y<0) {cy=-y; ch+=y; y=0; }; 1854 if (y<0) {cy=-y; ch+=y; y=0; };
1855 if (ch + y > lower.height()) { ch=lower.height()-y; }; 1855 if (ch + y > lower.height()) { ch=lower.height()-y; };
1856 1856
1857 if ( cx >= upper.width() || cy >= upper.height() ) return true; 1857 if ( cx >= upper.width() || cy >= upper.height() ) return true;
1858 if ( cw <= 0 || ch <= 0 ) return true; 1858 if ( cw <= 0 || ch <= 0 ) return true;
1859 } 1859 }
1860 1860
1861 output.create(cw,ch,32); 1861 output.create(cw,ch,32);
1862// output.setAlphaBuffer(true); // I should do some benchmarks to see if 1862// output.setAlphaBuffer(true); // I should do some benchmarks to see if
1863 // this is worth the effort 1863 // this is worth the effort
1864 1864
1865 register QRgb *i, *o, *b; 1865 register QRgb *i, *o, *b;
1866 1866
1867 register int a; 1867 register int a;
1868 register int j,k; 1868 register int j,k;
1869 for (j=0; j<ch; j++) 1869 for (j=0; j<ch; j++)
1870 { 1870 {
1871 b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); 1871 b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]);
1872 i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); 1872 i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]);
1873 o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); 1873 o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]);
1874 1874
1875 k=cw-1; 1875 k=cw-1;
1876 --b; --i; --o; 1876 --b; --i; --o;
1877 do 1877 do
1878 { 1878 {
1879 while ( !(a=qAlpha(*i)) && k>0 ) 1879 while ( !(a=qAlpha(*i)) && k>0 )
1880 { 1880 {
1881 i--; 1881 i--;
1882 //*o=0; 1882 //*o=0;
1883 *o=*b; 1883 *o=*b;
1884 --o; --b; 1884 --o; --b;
1885 k--; 1885 k--;
1886 }; 1886 };
1887// *o=0xFF; 1887// *o=0xFF;
1888 *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), 1888 *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8),
1889 qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), 1889 qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8),
1890 qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); 1890 qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8));
1891 --i; --o; --b; 1891 --i; --o; --b;
1892 } while (k--); 1892 } while (k--);
1893 } 1893 }
1894 1894
1895 return true; 1895 return true;
1896} 1896}
1897 1897
1898bool OImageEffect::blendOnLower( 1898bool OImageEffect::blendOnLower(
1899 int x, int y, 1899 int x, int y,
1900 const QImage & upper, 1900 const QImage & upper,
1901 const QImage & lower 1901 const QImage & lower
1902) 1902)
1903{ 1903{
1904 int cx=0, cy=0, cw=upper.width(), ch=upper.height(); 1904 int cx=0, cy=0, cw=upper.width(), ch=upper.height();
1905 1905
1906 if ( upper.depth() != 32 || lower.depth() != 32 ) return false; 1906 if ( upper.depth() != 32 || lower.depth() != 32 ) return false;
1907 if ( x + cw > lower.width() || 1907 if ( x + cw > lower.width() ||
1908 y + ch > lower.height() || 1908 y + ch > lower.height() ||
1909 x < 0 || y < 0 ) 1909 x < 0 || y < 0 )
1910 { 1910 {
1911 if ( x > lower.width() || y > lower.height() ) return true; 1911 if ( x > lower.width() || y > lower.height() ) return true;
1912 if ( upper.width()<=0 || upper.height() <= 0 ) return true; 1912 if ( upper.width()<=0 || upper.height() <= 0 ) return true;
1913 if ( lower.width()<=0 || lower.height() <= 0 ) return true; 1913 if ( lower.width()<=0 || lower.height() <= 0 ) return true;
1914 1914
1915 if (x<0) {cx=-x; cw+=x; x=0; }; 1915 if (x<0) {cx=-x; cw+=x; x=0; };
1916 if (cw + x > lower.width()) { cw=lower.width()-x; }; 1916 if (cw + x > lower.width()) { cw=lower.width()-x; };
1917 if (y<0) {cy=-y; ch+=y; y=0; }; 1917 if (y<0) {cy=-y; ch+=y; y=0; };
1918 if (ch + y > lower.height()) { ch=lower.height()-y; }; 1918 if (ch + y > lower.height()) { ch=lower.height()-y; };
1919 1919
1920 if ( cx >= upper.width() || cy >= upper.height() ) return true; 1920 if ( cx >= upper.width() || cy >= upper.height() ) return true;
1921 if ( cw <= 0 || ch <= 0 ) return true; 1921 if ( cw <= 0 || ch <= 0 ) return true;
1922 } 1922 }
1923 1923
1924 register uchar *i, *b; 1924 register uchar *i, *b;
1925 register int a; 1925 register int a;
1926 register int k; 1926 register int k;
1927 1927
1928 for (int j=0; j<ch; j++) 1928 for (int j=0; j<ch; j++)
1929 { 1929 {
1930 b=&lower.scanLine(y+j) [ (x+cw) << 2 ]; 1930 b=&lower.scanLine(y+j) [ (x+cw) << 2 ];
1931 i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ]; 1931 i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ];
1932 1932
1933 k=cw-1; 1933 k=cw-1;
1934 --b; --i; 1934 --b; --i;
1935 do 1935 do
1936 { 1936 {
1937#ifndef WORDS_BIGENDIAN 1937#ifndef WORDS_BIGENDIAN
1938 while ( !(a=*i) && k>0 ) 1938 while ( !(a=*i) && k>0 )
1939#else 1939#else
1940 while ( !(a=*(i-3)) && k>0 ) 1940 while ( !(a=*(i-3)) && k>0 )
1941#endif 1941#endif
1942 { 1942 {
1943 i-=4; b-=4; k--; 1943 i-=4; b-=4; k--;
1944 }; 1944 };
1945 1945
1946#ifndef WORDS_BIGENDIAN 1946#ifndef WORDS_BIGENDIAN
1947 --i; --b; 1947 --i; --b;
1948 *b += ( ((*i - *b) * a) >> 8 ); 1948 *b += ( ((*i - *b) * a) >> 8 );
1949 --i; --b; 1949 --i; --b;
1950 *b += ( ((*i - *b) * a) >> 8 ); 1950 *b += ( ((*i - *b) * a) >> 8 );
1951 --i; --b; 1951 --i; --b;
1952 *b += ( ((*i - *b) * a) >> 8 ); 1952 *b += ( ((*i - *b) * a) >> 8 );
1953 --i; --b; 1953 --i; --b;
1954#else 1954#else
1955 *b += ( ((*i - *b) * a) >> 8 ); 1955 *b += ( ((*i - *b) * a) >> 8 );
1956 --i; --b; 1956 --i; --b;
1957 *b += ( ((*i - *b) * a) >> 8 ); 1957 *b += ( ((*i - *b) * a) >> 8 );
1958 --i; --b; 1958 --i; --b;
1959 *b += ( ((*i - *b) * a) >> 8 ); 1959 *b += ( ((*i - *b) * a) >> 8 );
1960 i -= 2; b -= 2; 1960 i -= 2; b -= 2;
1961#endif 1961#endif
1962 } while (k--); 1962 } while (k--);
1963 } 1963 }
1964 1964
1965 return true; 1965 return true;
1966} 1966}
1967 1967
1968// For selected icons 1968// For selected icons
1969QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) 1969QImage& OImageEffect::selectedImage( QImage &img, const QColor &col )
1970{ 1970{
1971 return blend( col, img, 0.5); 1971 return blend( col, img, 0.5);
1972} 1972}
1973 1973
1974// 1974//
1975// =================================================================== 1975// ===================================================================
1976// Effects originally ported from ImageMagick for PixiePlus, plus a few 1976// Effects originally ported from ImageMagick for PixiePlus, plus a few
1977// new ones. (mosfet 12/29/01) 1977// new ones. (mosfet 12/29/01)
1978// =================================================================== 1978// ===================================================================
1979// 1979//
1980 1980
1981void OImageEffect::normalize(QImage &img) 1981void OImageEffect::normalize(QImage &img)
1982{ 1982{
1983 int *histogram, threshold_intensity, intense; 1983 int *histogram, threshold_intensity, intense;
1984 int x, y, i; 1984 int x, y, i;
1985 1985
1986 unsigned int gray_value; 1986 unsigned int gray_value;
1987 unsigned int *normalize_map; 1987 unsigned int *normalize_map;
1988 unsigned int high, low; 1988 unsigned int high, low;
1989 1989
1990 // allocate histogram and normalize map 1990 // allocate histogram and normalize map
1991 histogram = (int *)calloc(MaxRGB+1, sizeof(int)); 1991 histogram = (int *)calloc(MaxRGB+1, sizeof(int));
1992 normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int)); 1992 normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int));
1993 if(!normalize_map || !histogram){ 1993 if(!normalize_map || !histogram){
1994 owarn << "Unable to allocate normalize histogram and map" << oendl; 1994 owarn << "Unable to allocate normalize histogram and map" << oendl;
1995 free(normalize_map); 1995 free(normalize_map);
1996 free(histogram); 1996 free(histogram);
1997 return; 1997 return;
1998 } 1998 }
1999 1999
2000 // form histogram 2000 // form histogram
2001 if(img.depth() > 8){ // DirectClass 2001 if(img.depth() > 8){ // DirectClass
2002 unsigned int *data; 2002 unsigned int *data;
2003 for(y=0; y < img.height(); ++y){ 2003 for(y=0; y < img.height(); ++y){
2004 data = (unsigned int *)img.scanLine(y); 2004 data = (unsigned int *)img.scanLine(y);
2005 for(x=0; x < img.width(); ++x){ 2005 for(x=0; x < img.width(); ++x){
2006 gray_value = intensityValue(data[x]); 2006 gray_value = intensityValue(data[x]);
2007 histogram[gray_value]++; 2007 histogram[gray_value]++;
2008 } 2008 }
2009 } 2009 }
2010 } 2010 }
2011 else{ // PsudeoClass 2011 else{ // PsudeoClass
2012 unsigned char *data; 2012 unsigned char *data;
2013 unsigned int *cTable = img.colorTable(); 2013 unsigned int *cTable = img.colorTable();
2014 for(y=0; y < img.height(); ++y){ 2014 for(y=0; y < img.height(); ++y){
2015 data = (unsigned char *)img.scanLine(y); 2015 data = (unsigned char *)img.scanLine(y);
2016 for(x=0; x < img.width(); ++x){ 2016 for(x=0; x < img.width(); ++x){
2017 gray_value = intensityValue(*(cTable+data[x])); 2017 gray_value = intensityValue(*(cTable+data[x]));
2018 histogram[gray_value]++; 2018 histogram[gray_value]++;
2019 } 2019 }
2020 } 2020 }
2021 } 2021 }
2022 2022
2023 // find histogram boundaries by locating the 1 percent levels 2023 // find histogram boundaries by locating the 1 percent levels
2024 threshold_intensity = (img.width()*img.height())/100; 2024 threshold_intensity = (img.width()*img.height())/100;
2025 intense = 0; 2025 intense = 0;
2026 for(low=0; low < MaxRGB; ++low){ 2026 for(low=0; low < MaxRGB; ++low){
2027 intense+=histogram[low]; 2027 intense+=histogram[low];
2028 if(intense > threshold_intensity) 2028 if(intense > threshold_intensity)
2029 break; 2029 break;
2030 } 2030 }
2031 intense=0; 2031 intense=0;
2032 for(high=MaxRGB; high != 0; --high){ 2032 for(high=MaxRGB; high != 0; --high){
2033 intense+=histogram[high]; 2033 intense+=histogram[high];
2034 if(intense > threshold_intensity) 2034 if(intense > threshold_intensity)
2035 break; 2035 break;
2036 } 2036 }
2037 2037
2038 if (low == high){ 2038 if (low == high){
2039 // Unreasonable contrast; use zero threshold to determine boundaries. 2039 // Unreasonable contrast; use zero threshold to determine boundaries.
2040 threshold_intensity=0; 2040 threshold_intensity=0;
2041 intense=0; 2041 intense=0;
2042 for(low=0; low < MaxRGB; ++low){ 2042 for(low=0; low < MaxRGB; ++low){
2043 intense+=histogram[low]; 2043 intense+=histogram[low];
2044 if(intense > threshold_intensity) 2044 if(intense > threshold_intensity)
2045 break; 2045 break;
2046 } 2046 }
2047 intense=0; 2047 intense=0;
2048 for(high=MaxRGB; high != 0; --high) 2048 for(high=MaxRGB; high != 0; --high)
2049 { 2049 {
2050 intense+=histogram[high]; 2050 intense+=histogram[high];
2051 if(intense > threshold_intensity) 2051 if(intense > threshold_intensity)
2052 break; 2052 break;
2053 } 2053 }
2054 if(low == high) 2054 if(low == high) {
2055 free(histogram);
2056 free(normalize_map);
2055 return; // zero span bound 2057 return; // zero span bound
2058 }
2056 } 2059 }
2057 2060
2058 // Stretch the histogram to create the normalized image mapping. 2061 // Stretch the histogram to create the normalized image mapping.
2059 for(i=0; i <= MaxRGB; i++){ 2062 for(i=0; i <= MaxRGB; i++){
2060 if (i < (int) low) 2063 if (i < (int) low)
2061 normalize_map[i]=0; 2064 normalize_map[i]=0;
2062 else{ 2065 else{
2063 if(i > (int) high) 2066 if(i > (int) high)
2064 normalize_map[i]=MaxRGB; 2067 normalize_map[i]=MaxRGB;
2065 else 2068 else
2066 normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low); 2069 normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low);
2067 } 2070 }
2068 } 2071 }
2069 // Normalize 2072 // Normalize
2070 if(img.depth() > 8){ // DirectClass 2073 if(img.depth() > 8){ // DirectClass
2071 unsigned int *data; 2074 unsigned int *data;
2072 for(y=0; y < img.height(); ++y){ 2075 for(y=0; y < img.height(); ++y){
2073 data = (unsigned int *)img.scanLine(y); 2076 data = (unsigned int *)img.scanLine(y);
2074 for(x=0; x < img.width(); ++x){ 2077 for(x=0; x < img.width(); ++x){
2075 data[x] = qRgba(normalize_map[qRed(data[x])], 2078 data[x] = qRgba(normalize_map[qRed(data[x])],
2076 normalize_map[qGreen(data[x])], 2079 normalize_map[qGreen(data[x])],
2077 normalize_map[qBlue(data[x])], 2080 normalize_map[qBlue(data[x])],
2078 qAlpha(data[x])); 2081 qAlpha(data[x]));
2079 } 2082 }
2080 } 2083 }
2081 } 2084 }
2082 else{ // PsudeoClass 2085 else{ // PsudeoClass
2083 int colors = img.numColors(); 2086 int colors = img.numColors();
2084 unsigned int *cTable = img.colorTable(); 2087 unsigned int *cTable = img.colorTable();
2085 for(i=0; i < colors; ++i){ 2088 for(i=0; i < colors; ++i){
2086 cTable[i] = qRgba(normalize_map[qRed(cTable[i])], 2089 cTable[i] = qRgba(normalize_map[qRed(cTable[i])],
2087 normalize_map[qGreen(cTable[i])], 2090 normalize_map[qGreen(cTable[i])],
2088 normalize_map[qBlue(cTable[i])], 2091 normalize_map[qBlue(cTable[i])],
2089 qAlpha(cTable[i])); 2092 qAlpha(cTable[i]));
2090 } 2093 }
2091 } 2094 }
2092 free(histogram); 2095 free(histogram);
2093 free(normalize_map); 2096 free(normalize_map);
2094} 2097}
2095 2098
2096 2099
2097void OImageEffect::equalize(QImage &img) 2100void OImageEffect::equalize(QImage &img)
2098{ 2101{
2099 int *histogram, *map, *equalize_map; 2102 int *histogram, *map, *equalize_map;
2100 int x, y, i, j; 2103 int x, y, i, j;
2101 2104
2102 unsigned int high, low; 2105 unsigned int high, low;
2103 2106
2104 // allocate histogram and maps 2107 // allocate histogram and maps
2105 histogram = (int *)calloc(MaxRGB+1, sizeof(int)); 2108 histogram = (int *)calloc(MaxRGB+1, sizeof(int));
2106 map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); 2109 map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int));
2107 equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); 2110 equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int));
2108 2111
2109 if(!histogram || !map || !equalize_map){ 2112 if(!histogram || !map || !equalize_map){
2110 owarn << "Unable to allocate equalize histogram and maps" << oendl; 2113 owarn << "Unable to allocate equalize histogram and maps" << oendl;
2111 free(histogram); 2114 free(histogram);
2112 free(map); 2115 free(map);
2113 free(equalize_map); 2116 free(equalize_map);
2114 return; 2117 return;
2115 } 2118 }
2116 // form histogram 2119 // form histogram
2117 if(img.depth() > 8){ // DirectClass 2120 if(img.depth() > 8){ // DirectClass
2118 unsigned int *data; 2121 unsigned int *data;
2119 for(y=0; y < img.height(); ++y){ 2122 for(y=0; y < img.height(); ++y){
2120 data = (unsigned int *)img.scanLine(y); 2123 data = (unsigned int *)img.scanLine(y);
2121 for(x=0; x < img.width(); ++x){ 2124 for(x=0; x < img.width(); ++x){
2122 histogram[intensityValue(data[x])]++; 2125 histogram[intensityValue(data[x])]++;
2123 } 2126 }
2124 } 2127 }
2125 } 2128 }
2126 else{ // PsudeoClass 2129 else{ // PsudeoClass
2127 unsigned char *data; 2130 unsigned char *data;
2128 unsigned int *cTable = img.colorTable(); 2131 unsigned int *cTable = img.colorTable();
2129 for(y=0; y < img.height(); ++y){ 2132 for(y=0; y < img.height(); ++y){
2130 data = (unsigned char *)img.scanLine(y); 2133 data = (unsigned char *)img.scanLine(y);
2131 for(x=0; x < img.width(); ++x){ 2134 for(x=0; x < img.width(); ++x){
2132 histogram[intensityValue(*(cTable+data[x]))]++; 2135 histogram[intensityValue(*(cTable+data[x]))]++;
2133 } 2136 }
2134 } 2137 }
2135 } 2138 }
2136 2139
2137 // integrate the histogram to get the equalization map. 2140 // integrate the histogram to get the equalization map.
2138 j=0; 2141 j=0;
2139 for(i=0; i <= MaxRGB; i++){ 2142 for(i=0; i <= MaxRGB; i++){
2140 j+=histogram[i]; 2143 j+=histogram[i];
2141 map[i]=j; 2144 map[i]=j;
2142 } 2145 }
2143 free(histogram); 2146 free(histogram);
2144 if(map[MaxRGB] == 0){ 2147 if(map[MaxRGB] == 0){
2145 free(equalize_map); 2148 free(equalize_map);
2146 free(map); 2149 free(map);
2147 return; 2150 return;
2148 } 2151 }
2149 // equalize 2152 // equalize
2150 low=map[0]; 2153 low=map[0];
2151 high=map[MaxRGB]; 2154 high=map[MaxRGB];
2152 for(i=0; i <= MaxRGB; i++) 2155 for(i=0; i <= MaxRGB; i++)
2153 equalize_map[i]=(unsigned int) 2156 equalize_map[i]=(unsigned int)
2154 ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1)); 2157 ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1));
2155 free(map); 2158 free(map);
2156 // stretch the histogram 2159 // stretch the histogram
2157 if(img.depth() > 8){ // DirectClass 2160 if(img.depth() > 8){ // DirectClass
2158 unsigned int *data; 2161 unsigned int *data;
2159 for(y=0; y < img.height(); ++y){ 2162 for(y=0; y < img.height(); ++y){
2160 data = (unsigned int *)img.scanLine(y); 2163 data = (unsigned int *)img.scanLine(y);
2161 for(x=0; x < img.width(); ++x){ 2164 for(x=0; x < img.width(); ++x){
2162 data[x] = qRgba(equalize_map[qRed(data[x])], 2165 data[x] = qRgba(equalize_map[qRed(data[x])],
2163 equalize_map[qGreen(data[x])], 2166 equalize_map[qGreen(data[x])],
2164 equalize_map[qBlue(data[x])], 2167 equalize_map[qBlue(data[x])],
2165 qAlpha(data[x])); 2168 qAlpha(data[x]));
2166 } 2169 }
2167 } 2170 }
2168 } 2171 }
2169 else{ // PsudeoClass 2172 else{ // PsudeoClass
2170 int colors = img.numColors(); 2173 int colors = img.numColors();
2171 unsigned int *cTable = img.colorTable(); 2174 unsigned int *cTable = img.colorTable();
2172 for(i=0; i < colors; ++i){ 2175 for(i=0; i < colors; ++i){
2173 cTable[i] = qRgba(equalize_map[qRed(cTable[i])], 2176 cTable[i] = qRgba(equalize_map[qRed(cTable[i])],
2174 equalize_map[qGreen(cTable[i])], 2177 equalize_map[qGreen(cTable[i])],
2175 equalize_map[qBlue(cTable[i])], 2178 equalize_map[qBlue(cTable[i])],
2176 qAlpha(cTable[i])); 2179 qAlpha(cTable[i]));
2177 } 2180 }
2178 } 2181 }
2179 free(equalize_map); 2182 free(equalize_map);
2180} 2183}
2181 2184
2182QImage OImageEffect::sample(QImage &src, int w, int h) 2185QImage OImageEffect::sample(QImage &src, int w, int h)
2183{ 2186{
2184 if(w == src.width() && h == src.height()) 2187 if(w == src.width() && h == src.height())
2185 return(src); 2188 return(src);
2186 2189
2187 double *x_offset, *y_offset; 2190 double *x_offset, *y_offset;
2188 int j, k, y; 2191 int j, k, y;
2189 register int x; 2192 register int x;
2190 QImage dest(w, h, src.depth()); 2193 QImage dest(w, h, src.depth());
2191 2194
2192 x_offset = (double *)malloc(w*sizeof(double)); 2195 x_offset = (double *)malloc(w*sizeof(double));
2193 y_offset = (double *)malloc(h*sizeof(double)); 2196 y_offset = (double *)malloc(h*sizeof(double));
2194 if(!x_offset || !y_offset){ 2197 if(!x_offset || !y_offset){
2195 owarn << "Unable to allocate pixels buffer" << oendl; 2198 owarn << "Unable to allocate pixels buffer" << oendl;
2196 free(x_offset); 2199 free(x_offset);
2197 free(y_offset); 2200 free(y_offset);
2198 return(src); 2201 return(src);
2199 } 2202 }
2200 2203
2201 // init pixel offsets 2204 // init pixel offsets
2202 for(x=0; x < w; ++x) 2205 for(x=0; x < w; ++x)
2203 x_offset[x] = x*src.width()/((double)w); 2206 x_offset[x] = x*src.width()/((double)w);
2204 for(y=0; y < h; ++y) 2207 for(y=0; y < h; ++y)
2205 y_offset[y] = y*src.height()/((double)h); 2208 y_offset[y] = y*src.height()/((double)h);
2206 2209
2207 // sample each row 2210 // sample each row
2208 if(src.depth() > 8){ // DirectClass source image 2211 if(src.depth() > 8){ // DirectClass source image
2209 unsigned int *srcData, *destData; 2212 unsigned int *srcData, *destData;
2210 unsigned int *pixels; 2213 unsigned int *pixels;
2211 pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int)); 2214 pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int));
2212 if(!pixels){ 2215 if(!pixels){
2213 owarn << "Unable to allocate pixels buffer" << oendl; 2216 owarn << "Unable to allocate pixels buffer" << oendl;
2214 free(pixels); 2217 free(pixels);
2215 free(x_offset); 2218 free(x_offset);
2216 free(y_offset); 2219 free(y_offset);
2217 return(src); 2220 return(src);
2218 } 2221 }
2219 j = (-1); 2222 j = (-1);
2220 for(y=0; y < h; ++y){ 2223 for(y=0; y < h; ++y){
2221 destData = (unsigned int *)dest.scanLine(y); 2224 destData = (unsigned int *)dest.scanLine(y);
2222 if(j != y_offset[y]){ 2225 if(j != y_offset[y]){
2223 // read a scan line 2226 // read a scan line
2224 j = (int)(y_offset[y]); 2227 j = (int)(y_offset[y]);
2225 srcData = (unsigned int *)src.scanLine(j); 2228 srcData = (unsigned int *)src.scanLine(j);
2226 (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int)); 2229 (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int));
2227 } 2230 }
2228 // sample each column 2231 // sample each column
2229 for(x=0; x < w; ++x){ 2232 for(x=0; x < w; ++x){
2230 k = (int)(x_offset[x]); 2233 k = (int)(x_offset[x]);
2231 destData[x] = pixels[k]; 2234 destData[x] = pixels[k];
2232 } 2235 }
2233 } 2236 }
2234 free(pixels); 2237 free(pixels);
2235 } 2238 }
2236 else{ // PsudeoClass source image 2239 else{ // PsudeoClass source image
2237 unsigned char *srcData, *destData; 2240 unsigned char *srcData, *destData;
2238 unsigned char *pixels; 2241 unsigned char *pixels;
2239 pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char)); 2242 pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char));
2240 if(!pixels){ 2243 if(!pixels){
2241 owarn << "Unable to allocate pixels buffer" << oendl; 2244 owarn << "Unable to allocate pixels buffer" << oendl;
2242 free(pixels); 2245 free(pixels);
2243 free(x_offset); 2246 free(x_offset);
2244 free(y_offset); 2247 free(y_offset);
2245 return(src); 2248 return(src);
2246 } 2249 }
2247 // copy colortable 2250 // copy colortable
2248 dest.setNumColors(src.numColors()); 2251 dest.setNumColors(src.numColors());
2249 (void)memcpy(dest.colorTable(), src.colorTable(), 2252 (void)memcpy(dest.colorTable(), src.colorTable(),
2250 src.numColors()*sizeof(unsigned int)); 2253 src.numColors()*sizeof(unsigned int));
2251 2254
2252 // sample image 2255 // sample image
2253 j = (-1); 2256 j = (-1);
2254 for(y=0; y < h; ++y){ 2257 for(y=0; y < h; ++y){
2255 destData = (unsigned char *)dest.scanLine(y); 2258 destData = (unsigned char *)dest.scanLine(y);
2256 if(j != y_offset[y]){ 2259 if(j != y_offset[y]){
2257 // read a scan line 2260 // read a scan line
2258 j = (int)(y_offset[y]); 2261 j = (int)(y_offset[y]);
2259 srcData = (unsigned char *)src.scanLine(j); 2262 srcData = (unsigned char *)src.scanLine(j);
2260 (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned char)); 2263 (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned char));
2261 } 2264 }
2262 // sample each column 2265 // sample each column
2263 for(x=0; x < w; ++x){ 2266 for(x=0; x < w; ++x){
2264 k = (int)(x_offset[x]); 2267 k = (int)(x_offset[x]);
2265 destData[x] = pixels[k]; 2268 destData[x] = pixels[k];
2266 } 2269 }
2267 } 2270 }
2268 free(pixels); 2271 free(pixels);
2269 } 2272 }
2270 free(x_offset); 2273 free(x_offset);
2271 free(y_offset); 2274 free(y_offset);
2272 return(dest); 2275 return(dest);
2273} 2276}
2274 2277
2275void OImageEffect::threshold(QImage &img, unsigned int threshold) 2278void OImageEffect::threshold(QImage &img, unsigned int threshold)
2276{ 2279{
2277 int i, count; 2280 int i, count;
2278 unsigned int *data; 2281 unsigned int *data;
2279 if(img.depth() > 8){ // DirectClass 2282 if(img.depth() > 8){ // DirectClass
2280 count = img.width()*img.height(); 2283 count = img.width()*img.height();
2281 data = (unsigned int *)img.bits(); 2284 data = (unsigned int *)img.bits();
2282 } 2285 }
2283 else{ // PsudeoClass 2286 else{ // PsudeoClass
2284 count = img.numColors(); 2287 count = img.numColors();
2285 data = (unsigned int *)img.colorTable(); 2288 data = (unsigned int *)img.colorTable();
2286 } 2289 }
2287 for(i=0; i < count; ++i) 2290 for(i=0; i < count; ++i)
2288 data[i] = intensityValue(data[i]) < threshold ? Qt::black.rgb() : Qt::white.rgb(); 2291 data[i] = intensityValue(data[i]) < threshold ? Qt::black.rgb() : Qt::white.rgb();
2289} 2292}
2290 2293
2291QImage OImageEffect::charcoal(QImage &src, double factor) 2294QImage OImageEffect::charcoal(QImage &src, double factor)
2292{ 2295{
2293 QImage dest(src); 2296 QImage dest(src);
2294 dest.detach(); 2297 dest.detach();
2295 toGray(dest); 2298 toGray(dest);
2296 dest = edge(dest, factor); 2299 dest = edge(dest, factor);
2297 dest = blur(dest, factor); 2300 dest = blur(dest, factor);
2298 normalize(dest); 2301 normalize(dest);
2299 dest.invertPixels(false); 2302 dest.invertPixels(false);
2300 return(dest); 2303 return(dest);
2301} 2304}
2302 2305
2303void OImageEffect::hull(const int x_offset, const int y_offset, 2306void OImageEffect::hull(const int x_offset, const int y_offset,
2304 const int polarity, const int columns, 2307 const int polarity, const int columns,
2305 const int rows, 2308 const int rows,
2306 unsigned int *f, unsigned int *g) 2309 unsigned int *f, unsigned int *g)
2307{ 2310{
2308 int x, y; 2311 int x, y;
2309 2312
2310 unsigned int *p, *q, *r, *s; 2313 unsigned int *p, *q, *r, *s;
2311 unsigned int v; 2314 unsigned int v;
2312 if(f == NULL || g == NULL) 2315 if(f == NULL || g == NULL)
2313 return; 2316 return;
2314 p=f+(columns+2); 2317 p=f+(columns+2);
2315 q=g+(columns+2); 2318 q=g+(columns+2);
2316 r=p+(y_offset*(columns+2)+x_offset); 2319 r=p+(y_offset*(columns+2)+x_offset);
2317 for (y=0; y < rows; y++){ 2320 for (y=0; y < rows; y++){
2318 p++; 2321 p++;
2319 q++; 2322 q++;
2320 r++; 2323 r++;
2321 if(polarity > 0) 2324 if(polarity > 0)
2322 for (x=0; x < columns; x++){ 2325 for (x=0; x < columns; x++){
2323 v=(*p); 2326 v=(*p);
2324 if (*r > v) 2327 if (*r > v)
2325 v++; 2328 v++;
2326 *q=v; 2329 *q=v;
2327 p++; 2330 p++;
2328 q++; 2331 q++;
2329 r++; 2332 r++;
2330 } 2333 }
2331 else 2334 else
2332 for(x=0; x < columns; x++){ 2335 for(x=0; x < columns; x++){
2333 v=(*p); 2336 v=(*p);
2334 if (v > (unsigned int) (*r+1)) 2337 if (v > (unsigned int) (*r+1))
2335 v--; 2338 v--;
2336 *q=v; 2339 *q=v;
2337 p++; 2340 p++;
2338 q++; 2341 q++;
2339 r++; 2342 r++;
2340 } 2343 }
2341 p++; 2344 p++;
2342 q++; 2345 q++;
2343 r++; 2346 r++;
2344 } 2347 }
2345 p=f+(columns+2); 2348 p=f+(columns+2);
2346 q=g+(columns+2); 2349 q=g+(columns+2);
2347 r=q+(y_offset*(columns+2)+x_offset); 2350 r=q+(y_offset*(columns+2)+x_offset);
2348 s=q-(y_offset*(columns+2)+x_offset); 2351 s=q-(y_offset*(columns+2)+x_offset);
2349 for(y=0; y < rows; y++){ 2352 for(y=0; y < rows; y++){
2350 p++; 2353 p++;
2351 q++; 2354 q++;
2352 r++; 2355 r++;
2353 s++; 2356 s++;
2354 if(polarity > 0) 2357 if(polarity > 0)
2355 for(x=0; x < (int) columns; x++){ 2358 for(x=0; x < (int) columns; x++){
2356 v=(*q); 2359 v=(*q);
2357 if (((unsigned int) (*s+1) > v) && (*r > v)) 2360 if (((unsigned int) (*s+1) > v) && (*r > v))
2358 v++; 2361 v++;
2359 *p=v; 2362 *p=v;
2360 p++; 2363 p++;
2361 q++; 2364 q++;
2362 r++; 2365 r++;
2363 s++; 2366 s++;
2364 } 2367 }
2365 else 2368 else
2366 for (x=0; x < columns; x++){ 2369 for (x=0; x < columns; x++){
2367 v=(*q); 2370 v=(*q);
2368 if (((unsigned int) (*s+1) < v) && (*r < v)) 2371 if (((unsigned int) (*s+1) < v) && (*r < v))
2369 v--; 2372 v--;
2370 *p=v; 2373 *p=v;
2371 p++; 2374 p++;
2372 q++; 2375 q++;
2373 r++; 2376 r++;
2374 s++; 2377 s++;
2375 } 2378 }
2376 p++; 2379 p++;
2377 q++; 2380 q++;
2378 r++; 2381 r++;
2379 s++; 2382 s++;
2380 } 2383 }
2381} 2384}
2382 2385
2383QImage OImageEffect::despeckle(QImage &src) 2386QImage OImageEffect::despeckle(QImage &src)
2384{ 2387{
2385 int i, j, x, y; 2388 int i, j, x, y;
2386 unsigned int *blue_channel, *red_channel, *green_channel, *buffer, 2389 unsigned int *blue_channel, *red_channel, *green_channel, *buffer,
2387 *alpha_channel; 2390 *alpha_channel;
2388 int packets; 2391 int packets;
2389 static const int 2392 static const int
2390 X[4]= {0, 1, 1,-1}, 2393 X[4]= {0, 1, 1,-1},
2391 Y[4]= {1, 0, 1, 1}; 2394 Y[4]= {1, 0, 1, 1};
2392 2395
2393 unsigned int *destData; 2396 unsigned int *destData;
2394 QImage dest(src.width(), src.height(), 32); 2397 QImage dest(src.width(), src.height(), 32);
2395 2398
2396 packets = (src.width()+2)*(src.height()+2); 2399 packets = (src.width()+2)*(src.height()+2);
2397 red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); 2400 red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int));
2398 green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); 2401 green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int));
2399 blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); 2402 blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int));
2400 alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); 2403 alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int));
2401 buffer = (unsigned int *)calloc(packets, sizeof(unsigned int)); 2404 buffer = (unsigned int *)calloc(packets, sizeof(unsigned int));
2402 if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || 2405 if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel ||
2403 !buffer){ 2406 !buffer){
2404 free(red_channel); 2407 free(red_channel);
2405 free(green_channel); 2408 free(green_channel);
2406 free(blue_channel); 2409 free(blue_channel);
2407 free(alpha_channel); 2410 free(alpha_channel);
2408 free(buffer); 2411 free(buffer);
2409 return(src); 2412 return(src);
2410 } 2413 }
2411 2414
2412 // copy image pixels to color component buffers 2415 // copy image pixels to color component buffers
2413 j = src.width()+2; 2416 j = src.width()+2;
2414 if(src.depth() > 8){ // DirectClass source image 2417 if(src.depth() > 8){ // DirectClass source image
2415 unsigned int *srcData; 2418 unsigned int *srcData;
2416 for(y=0; y < src.height(); ++y){ 2419 for(y=0; y < src.height(); ++y){
2417 srcData = (unsigned int *)src.scanLine(y); 2420 srcData = (unsigned int *)src.scanLine(y);
2418 ++j; 2421 ++j;
2419 for(x=0; x < src.width(); ++x){ 2422 for(x=0; x < src.width(); ++x){
2420 red_channel[j] = qRed(srcData[x]); 2423 red_channel[j] = qRed(srcData[x]);
2421 green_channel[j] = qGreen(srcData[x]); 2424 green_channel[j] = qGreen(srcData[x]);
2422 blue_channel[j] = qBlue(srcData[x]); 2425 blue_channel[j] = qBlue(srcData[x]);
2423 alpha_channel[j] = qAlpha(srcData[x]); 2426 alpha_channel[j] = qAlpha(srcData[x]);
2424 ++j; 2427 ++j;
2425 } 2428 }
2426 ++j; 2429 ++j;
2427 } 2430 }
2428 } 2431 }
2429 else{ // PsudeoClass source image 2432 else{ // PsudeoClass source image
2430 unsigned char *srcData; 2433 unsigned char *srcData;
2431 unsigned int *cTable = src.colorTable(); 2434 unsigned int *cTable = src.colorTable();
2432 unsigned int pixel; 2435 unsigned int pixel;
2433 for(y=0; y < src.height(); ++y){ 2436 for(y=0; y < src.height(); ++y){
2434 srcData = (unsigned char *)src.scanLine(y); 2437 srcData = (unsigned char *)src.scanLine(y);
2435 ++j; 2438 ++j;
2436 for(x=0; x < src.width(); ++x){ 2439 for(x=0; x < src.width(); ++x){
2437 pixel = *(cTable+srcData[x]); 2440 pixel = *(cTable+srcData[x]);
2438 red_channel[j] = qRed(pixel); 2441 red_channel[j] = qRed(pixel);
2439 green_channel[j] = qGreen(pixel); 2442 green_channel[j] = qGreen(pixel);
2440 blue_channel[j] = qBlue(pixel); 2443 blue_channel[j] = qBlue(pixel);
2441 alpha_channel[j] = qAlpha(pixel); 2444 alpha_channel[j] = qAlpha(pixel);
2442 ++j; 2445 ++j;
2443 } 2446 }
2444 ++j; 2447 ++j;
2445 } 2448 }
2446 } 2449 }
2447 // reduce speckle in red channel 2450 // reduce speckle in red channel
2448 for(i=0; i < 4; i++){ 2451 for(i=0; i < 4; i++){
2449 hull(X[i],Y[i],1,src.width(),src.height(),red_channel,buffer); 2452 hull(X[i],Y[i],1,src.width(),src.height(),red_channel,buffer);
2450 hull(-X[i],-Y[i],1,src.width(),src.height(),red_channel,buffer); 2453 hull(-X[i],-Y[i],1,src.width(),src.height(),red_channel,buffer);
2451 hull(-X[i],-Y[i],-1,src.width(),src.height(),red_channel,buffer); 2454 hull(-X[i],-Y[i],-1,src.width(),src.height(),red_channel,buffer);
2452 hull(X[i],Y[i],-1,src.width(),src.height(),red_channel,buffer); 2455 hull(X[i],Y[i],-1,src.width(),src.height(),red_channel,buffer);
2453 } 2456 }
2454 // reduce speckle in green channel 2457 // reduce speckle in green channel
2455 for (i=0; i < packets; i++) 2458 for (i=0; i < packets; i++)
2456 buffer[i]=0; 2459 buffer[i]=0;
2457 for (i=0; i < 4; i++){ 2460 for (i=0; i < 4; i++){
2458 hull(X[i],Y[i],1,src.width(),src.height(),green_channel,buffer); 2461 hull(X[i],Y[i],1,src.width(),src.height(),green_channel,buffer);
2459 hull(-X[i],-Y[i],1,src.width(),src.height(),green_channel,buffer); 2462 hull(-X[i],-Y[i],1,src.width(),src.height(),green_channel,buffer);
2460 hull(-X[i],-Y[i],-1,src.width(),src.height(),green_channel,buffer); 2463 hull(-X[i],-Y[i],-1,src.width(),src.height(),green_channel,buffer);
2461 hull(X[i],Y[i],-1,src.width(),src.height(),green_channel,buffer); 2464 hull(X[i],Y[i],-1,src.width(),src.height(),green_channel,buffer);
2462 } 2465 }
2463 // reduce speckle in blue channel 2466 // reduce speckle in blue channel
2464 for (i=0; i < packets; i++) 2467 for (i=0; i < packets; i++)
2465 buffer[i]=0; 2468 buffer[i]=0;
2466 for (i=0; i < 4; i++){ 2469 for (i=0; i < 4; i++){
2467 hull(X[i],Y[i],1,src.width(),src.height(),blue_channel,buffer); 2470 hull(X[i],Y[i],1,src.width(),src.height(),blue_channel,buffer);
2468 hull(-X[i],-Y[i],1,src.width(),src.height(),blue_channel,buffer); 2471 hull(-X[i],-Y[i],1,src.width(),src.height(),blue_channel,buffer);
2469 hull(-X[i],-Y[i],-1,src.width(),src.height(),blue_channel,buffer); 2472 hull(-X[i],-Y[i],-1,src.width(),src.height(),blue_channel,buffer);
2470 hull(X[i],Y[i],-1,src.width(),src.height(),blue_channel,buffer); 2473 hull(X[i],Y[i],-1,src.width(),src.height(),blue_channel,buffer);
2471 } 2474 }
2472 // copy color component buffers to despeckled image 2475 // copy color component buffers to despeckled image
2473 j = dest.width()+2; 2476 j = dest.width()+2;
2474 for(y=0; y < dest.height(); ++y) 2477 for(y=0; y < dest.height(); ++y)
2475 { 2478 {
2476 destData = (unsigned int *)dest.scanLine(y); 2479 destData = (unsigned int *)dest.scanLine(y);
2477 ++j; 2480 ++j;
2478 for (x=0; x < dest.width(); ++x) 2481 for (x=0; x < dest.width(); ++x)
2479 { 2482 {
2480 destData[x] = qRgba(red_channel[j], green_channel[j], 2483 destData[x] = qRgba(red_channel[j], green_channel[j],
2481 blue_channel[j], alpha_channel[j]); 2484 blue_channel[j], alpha_channel[j]);
2482 ++j; 2485 ++j;
2483 } 2486 }
2484 ++j; 2487 ++j;
2485 } 2488 }
2486 free(buffer); 2489 free(buffer);
2487 free(red_channel); 2490 free(red_channel);
2488 free(green_channel); 2491 free(green_channel);
2489 free(blue_channel); 2492 free(blue_channel);
2490 free(alpha_channel); 2493 free(alpha_channel);
2491 return(dest); 2494 return(dest);
2492} 2495}
2493 2496
2494unsigned int OImageEffect::generateNoise(unsigned int pixel, 2497unsigned int OImageEffect::generateNoise(unsigned int pixel,
2495 NoiseType noise_type) 2498 NoiseType noise_type)
2496{ 2499{
2497#define NoiseEpsilon 1.0e-5 2500#define NoiseEpsilon 1.0e-5
2498#define NoiseMask 0x7fff 2501#define NoiseMask 0x7fff
2499#define SigmaUniform 4.0 2502#define SigmaUniform 4.0
2500#define SigmaGaussian 4.0 2503#define SigmaGaussian 4.0
2501#define SigmaImpulse 0.10 2504#define SigmaImpulse 0.10
2502#define SigmaLaplacian 10.0 2505#define SigmaLaplacian 10.0
2503#define SigmaMultiplicativeGaussian 0.5 2506#define SigmaMultiplicativeGaussian 0.5
2504#define SigmaPoisson 0.05 2507#define SigmaPoisson 0.05
2505#define TauGaussian 20.0 2508#define TauGaussian 20.0
2506 2509
2507 double alpha, beta, sigma, value; 2510 double alpha, beta, sigma, value;
2508 alpha=(double) (rand() & NoiseMask)/NoiseMask; 2511 alpha=(double) (rand() & NoiseMask)/NoiseMask;
2509 if (alpha == 0.0) 2512 if (alpha == 0.0)
2510 alpha=1.0; 2513 alpha=1.0;
2511 switch(noise_type){ 2514 switch(noise_type){
2512 case UniformNoise: 2515 case UniformNoise:
2513 default: 2516 default:
2514 { 2517 {
2515 value=(double) pixel+SigmaUniform*(alpha-0.5); 2518 value=(double) pixel+SigmaUniform*(alpha-0.5);
2516 break; 2519 break;
2517 } 2520 }
2518 case GaussianNoise: 2521 case GaussianNoise:
2519 { 2522 {
2520 double tau; 2523 double tau;
2521 2524
2522 beta=(double) (rand() & NoiseMask)/NoiseMask; 2525 beta=(double) (rand() & NoiseMask)/NoiseMask;
2523 sigma=sqrt(-2.0*log(alpha))*cos(2.0*M_PI*beta); 2526 sigma=sqrt(-2.0*log(alpha))*cos(2.0*M_PI*beta);
2524 tau=sqrt(-2.0*log(alpha))*sin(2.0*M_PI*beta); 2527 tau=sqrt(-2.0*log(alpha))*sin(2.0*M_PI*beta);
2525 value=(double) pixel+ 2528 value=(double) pixel+
2526 (sqrt((double) pixel)*SigmaGaussian*sigma)+(TauGaussian*tau); 2529 (sqrt((double) pixel)*SigmaGaussian*sigma)+(TauGaussian*tau);
2527 break; 2530 break;
2528 } 2531 }
2529 case MultiplicativeGaussianNoise: 2532 case MultiplicativeGaussianNoise:
2530 { 2533 {
2531 if (alpha <= NoiseEpsilon) 2534 if (alpha <= NoiseEpsilon)
2532 sigma=MaxRGB; 2535 sigma=MaxRGB;
2533 else 2536 else
2534 sigma=sqrt(-2.0*log(alpha)); 2537 sigma=sqrt(-2.0*log(alpha));
2535 beta=(rand() & NoiseMask)/NoiseMask; 2538 beta=(rand() & NoiseMask)/NoiseMask;
2536 value=(double) pixel+ 2539 value=(double) pixel+
2537 pixel*SigmaMultiplicativeGaussian*sigma*cos(2.0*M_PI*beta); 2540 pixel*SigmaMultiplicativeGaussian*sigma*cos(2.0*M_PI*beta);
2538 break; 2541 break;
2539 } 2542 }
2540 case ImpulseNoise: 2543 case ImpulseNoise:
2541 { 2544 {
2542 if (alpha < (SigmaImpulse/2.0)) 2545 if (alpha < (SigmaImpulse/2.0))
2543 value=0; 2546 value=0;
2544 else 2547 else
2545 if (alpha >= (1.0-(SigmaImpulse/2.0))) 2548 if (alpha >= (1.0-(SigmaImpulse/2.0)))
2546 value=MaxRGB; 2549 value=MaxRGB;
2547 else 2550 else
2548 value=pixel; 2551 value=pixel;
2549 break; 2552 break;
2550 } 2553 }
2551 case LaplacianNoise: 2554 case LaplacianNoise:
2552 { 2555 {
2553 if (alpha <= 0.5) 2556 if (alpha <= 0.5)
2554 { 2557 {
2555 if (alpha <= NoiseEpsilon) 2558 if (alpha <= NoiseEpsilon)
2556 value=(double) pixel-MaxRGB; 2559 value=(double) pixel-MaxRGB;
2557 else 2560 else
2558 value=(double) pixel+SigmaLaplacian*log(2.0*alpha); 2561 value=(double) pixel+SigmaLaplacian*log(2.0*alpha);
2559 break; 2562 break;
2560 } 2563 }
2561 beta=1.0-alpha; 2564 beta=1.0-alpha;
2562 if (beta <= (0.5*NoiseEpsilon)) 2565 if (beta <= (0.5*NoiseEpsilon))
2563 value=(double) pixel+MaxRGB; 2566 value=(double) pixel+MaxRGB;
2564 else 2567 else
2565 value=(double) pixel-SigmaLaplacian*log(2.0*beta); 2568 value=(double) pixel-SigmaLaplacian*log(2.0*beta);
2566 break; 2569 break;
2567 } 2570 }
2568 case PoissonNoise: 2571 case PoissonNoise:
2569 { 2572 {
2570 register int 2573 register int
2571 i; 2574 i;
2572 2575
2573 for (i=0; alpha > exp(-SigmaPoisson*pixel); i++) 2576 for (i=0; alpha > exp(-SigmaPoisson*pixel); i++)
2574 { 2577 {
2575 beta=(double) (rand() & NoiseMask)/NoiseMask; 2578 beta=(double) (rand() & NoiseMask)/NoiseMask;
2576 alpha=alpha*beta; 2579 alpha=alpha*beta;
2577 } 2580 }
2578 value=i/SigmaPoisson; 2581 value=i/SigmaPoisson;
2579 break; 2582 break;
2580 } 2583 }
2581 } 2584 }
2582 if(value < 0.0) 2585 if(value < 0.0)
2583 return(0); 2586 return(0);
2584 if(value > MaxRGB) 2587 if(value > MaxRGB)
2585 return(MaxRGB); 2588 return(MaxRGB);
2586 return((unsigned int) (value+0.5)); 2589 return((unsigned int) (value+0.5));
2587} 2590}
2588 2591
2589QImage OImageEffect::addNoise(QImage &src, NoiseType noise_type) 2592QImage OImageEffect::addNoise(QImage &src, NoiseType noise_type)
2590{ 2593{
2591 int x, y; 2594 int x, y;
2592 QImage dest(src.width(), src.height(), 32); 2595 QImage dest(src.width(), src.height(), 32);
2593 unsigned int *destData; 2596 unsigned int *destData;
2594 2597
2595 if(src.depth() > 8){ // DirectClass source image 2598 if(src.depth() > 8){ // DirectClass source image
2596 unsigned int *srcData; 2599 unsigned int *srcData;
2597 for(y=0; y < src.height(); ++y){ 2600 for(y=0; y < src.height(); ++y){
2598 srcData = (unsigned int *)src.scanLine(y); 2601 srcData = (unsigned int *)src.scanLine(y);
2599 destData = (unsigned int *)dest.scanLine(y); 2602 destData = (unsigned int *)dest.scanLine(y);
2600 for(x=0; x < src.width(); ++x){ 2603 for(x=0; x < src.width(); ++x){
2601 destData[x] = qRgba(generateNoise(qRed(srcData[x]), noise_type), 2604 destData[x] = qRgba(generateNoise(qRed(srcData[x]), noise_type),
2602 generateNoise(qGreen(srcData[x]), noise_type), 2605 generateNoise(qGreen(srcData[x]), noise_type),
2603 generateNoise(qBlue(srcData[x]), noise_type), 2606 generateNoise(qBlue(srcData[x]), noise_type),
2604 qAlpha(srcData[x])); 2607 qAlpha(srcData[x]));
2605 } 2608 }
2606 } 2609 }
2607 } 2610 }
2608 else{ // PsudeoClass source image 2611 else{ // PsudeoClass source image
2609 unsigned char *srcData; 2612 unsigned char *srcData;
2610 unsigned int *cTable = src.colorTable(); 2613 unsigned int *cTable = src.colorTable();
2611 unsigned int pixel; 2614 unsigned int pixel;
2612 for(y=0; y < src.height(); ++y){ 2615 for(y=0; y < src.height(); ++y){
2613 srcData = (unsigned char *)src.scanLine(y); 2616 srcData = (unsigned char *)src.scanLine(y);
2614 destData = (unsigned int *)dest.scanLine(y); 2617 destData = (unsigned int *)dest.scanLine(y);
2615 for(x=0; x < src.width(); ++x){ 2618 for(x=0; x < src.width(); ++x){
2616 pixel = *(cTable+srcData[x]); 2619 pixel = *(cTable+srcData[x]);
2617 destData[x] = qRgba(generateNoise(qRed(pixel), noise_type), 2620 destData[x] = qRgba(generateNoise(qRed(pixel), noise_type),
2618 generateNoise(qGreen(pixel), noise_type), 2621 generateNoise(qGreen(pixel), noise_type),
2619 generateNoise(qBlue(pixel), noise_type), 2622 generateNoise(qBlue(pixel), noise_type),
2620 qAlpha(pixel)); 2623 qAlpha(pixel));
2621 } 2624 }
2622 } 2625 }
2623 2626
2624 } 2627 }
2625 return(dest); 2628 return(dest);
2626} 2629}
2627 2630
2628unsigned int OImageEffect::interpolateColor(QImage *image, double x_offset, 2631unsigned int OImageEffect::interpolateColor(QImage *image, double x_offset,
2629 double y_offset, 2632 double y_offset,
2630 unsigned int background) 2633 unsigned int background)
2631{ 2634{
2632 double alpha, beta; 2635 double alpha, beta;
2633 unsigned int p, q, r, s; 2636 unsigned int p, q, r, s;
2634 int x, y; 2637 int x, y;
2635 2638
2636 x = (int)x_offset; 2639 x = (int)x_offset;
2637 y = (int)y_offset; 2640 y = (int)y_offset;
2638 if((x < -1) || (x >= image->width()) || (y < -1) || (y >= image->height())) 2641 if((x < -1) || (x >= image->width()) || (y < -1) || (y >= image->height()))
2639 return(background); 2642 return(background);
2640 if(image->depth() > 8){ 2643 if(image->depth() > 8){
2641 if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) { 2644 if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) {
2642 unsigned int *t = (unsigned int *)image->scanLine(y); 2645 unsigned int *t = (unsigned int *)image->scanLine(y);
2643 p = t[x]; 2646 p = t[x];
2644 q = t[x+1]; 2647 q = t[x+1];
2645 r = t[x+image->width()]; 2648 r = t[x+image->width()];
2646 s = t[x+image->width()+1]; 2649 s = t[x+image->width()+1];
2647 } 2650 }
2648 else{ 2651 else{
2649 unsigned int *t = (unsigned int *)image->scanLine(y); 2652 unsigned int *t = (unsigned int *)image->scanLine(y);
2650 p = background; 2653 p = background;
2651 if((x >= 0) && (y >= 0)){ 2654 if((x >= 0) && (y >= 0)){
2652 p = t[x]; 2655 p = t[x];
2653 } 2656 }
2654 q = background; 2657 q = background;
2655 if(((x+1) < image->width()) && (y >= 0)){ 2658 if(((x+1) < image->width()) && (y >= 0)){
2656 q = t[x+1]; 2659 q = t[x+1];
2657 } 2660 }
2658 r = background; 2661 r = background;
2659 if((x >= 0) && ((y+1) < image->height())){ 2662 if((x >= 0) && ((y+1) < image->height())){
2660 t = (unsigned int *)image->scanLine(y+1); 2663 t = (unsigned int *)image->scanLine(y+1);
2661 r = t[x+image->width()]; 2664 r = t[x+image->width()];
2662 } 2665 }
2663 s = background; 2666 s = background;
2664 if(((x+1) < image->width()) && ((y+1) < image->height())){ 2667 if(((x+1) < image->width()) && ((y+1) < image->height())){
2665 t = (unsigned int *)image->scanLine(y+1); 2668 t = (unsigned int *)image->scanLine(y+1);
2666 s = t[x+image->width()+1]; 2669 s = t[x+image->width()+1];
2667 } 2670 }
2668 2671
2669 } 2672 }
2670 } 2673 }
2671 else{ 2674 else{
2672 unsigned int *colorTable = (unsigned int *)image->colorTable(); 2675 unsigned int *colorTable = (unsigned int *)image->colorTable();
2673 if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) { 2676 if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) {
2674 unsigned char *t; 2677 unsigned char *t;
2675 t = (unsigned char *)image->scanLine(y); 2678 t = (unsigned char *)image->scanLine(y);
2676 p = *(colorTable+t[x]); 2679 p = *(colorTable+t[x]);
2677 q = *(colorTable+t[x+1]); 2680 q = *(colorTable+t[x+1]);
2678 t = (unsigned char *)image->scanLine(y+1); 2681 t = (unsigned char *)image->scanLine(y+1);
2679 r = *(colorTable+t[x]); 2682 r = *(colorTable+t[x]);
2680 s = *(colorTable+t[x+1]); 2683 s = *(colorTable+t[x+1]);
2681 } 2684 }
2682 else{ 2685 else{
2683 unsigned char *t; 2686 unsigned char *t;
2684 p = background; 2687 p = background;
2685 if((x >= 0) && (y >= 0)){ 2688 if((x >= 0) && (y >= 0)){
2686 t = (unsigned char *)image->scanLine(y); 2689 t = (unsigned char *)image->scanLine(y);
2687 p = *(colorTable+t[x]); 2690 p = *(colorTable+t[x]);
2688 } 2691 }
2689 q = background; 2692 q = background;
2690 if(((x+1) < image->width()) && (y >= 0)){ 2693 if(((x+1) < image->width()) && (y >= 0)){
2691 t = (unsigned char *)image->scanLine(y); 2694 t = (unsigned char *)image->scanLine(y);
2692 q = *(colorTable+t[x+1]); 2695 q = *(colorTable+t[x+1]);
2693 } 2696 }
2694 r = background; 2697 r = background;
2695 if((x >= 0) && ((y+1) < image->height())){ 2698 if((x >= 0) && ((y+1) < image->height())){
2696 t = (unsigned char *)image->scanLine(y+1); 2699 t = (unsigned char *)image->scanLine(y+1);
2697 r = *(colorTable+t[x]); 2700 r = *(colorTable+t[x]);
2698 } 2701 }
2699 s = background; 2702 s = background;
2700 if(((x+1) < image->width()) && ((y+1) < image->height())){ 2703 if(((x+1) < image->width()) && ((y+1) < image->height())){
2701 t = (unsigned char *)image->scanLine(y+1); 2704 t = (unsigned char *)image->scanLine(y+1);
2702 s = *(colorTable+t[x+1]); 2705 s = *(colorTable+t[x+1]);
2703 } 2706 }
2704 2707
2705 } 2708 }
2706 2709
2707 } 2710 }
2708 x_offset -= floor(x_offset); 2711 x_offset -= floor(x_offset);
2709 y_offset -= floor(y_offset); 2712 y_offset -= floor(y_offset);
2710 alpha = 1.0-x_offset; 2713 alpha = 1.0-x_offset;
2711 beta = 1.0-y_offset; 2714 beta = 1.0-y_offset;
2712 2715
2713 return(qRgba((unsigned char)(beta*(alpha*qRed(p)+x_offset*qRed(q))+y_offset*(alpha*qRed(r)+x_offset*qRed(s))), 2716 return(qRgba((unsigned char)(beta*(alpha*qRed(p)+x_offset*qRed(q))+y_offset*(alpha*qRed(r)+x_offset*qRed(s))),
2714 (unsigned char)(beta*(alpha*qGreen(p)+x_offset*qGreen(q))+y_offset*(alpha*qGreen(r)+x_offset*qGreen(s))), 2717 (unsigned char)(beta*(alpha*qGreen(p)+x_offset*qGreen(q))+y_offset*(alpha*qGreen(r)+x_offset*qGreen(s))),
2715 (unsigned char)(beta*(alpha*qBlue(p)+x_offset*qBlue(q))+y_offset*(alpha*qBlue(r)+x_offset*qBlue(s))), 2718 (unsigned char)(beta*(alpha*qBlue(p)+x_offset*qBlue(q))+y_offset*(alpha*qBlue(r)+x_offset*qBlue(s))),
2716 (unsigned char)(beta*(alpha*qAlpha(p)+x_offset*qAlpha(q))+y_offset*(alpha*qAlpha(r)+x_offset*qAlpha(s))))); 2719 (unsigned char)(beta*(alpha*qAlpha(p)+x_offset*qAlpha(q))+y_offset*(alpha*qAlpha(r)+x_offset*qAlpha(s)))));
2717} 2720}
2718 2721
2719QImage OImageEffect::implode(QImage &src, double factor, 2722QImage OImageEffect::implode(QImage &src, double factor,
2720 unsigned int background) 2723 unsigned int background)
2721{ 2724{
2722 double amount, distance, radius; 2725 double amount, distance, radius;
2723 double x_center, x_distance, x_scale; 2726 double x_center, x_distance, x_scale;
2724 double y_center, y_distance, y_scale; 2727 double y_center, y_distance, y_scale;
2725 unsigned int *destData; 2728 unsigned int *destData;
2726 int x, y; 2729 int x, y;
2727 2730
2728 QImage dest(src.width(), src.height(), 32); 2731 QImage dest(src.width(), src.height(), 32);
2729 2732
2730 // compute scaling factor 2733 // compute scaling factor
2731 x_scale = 1.0; 2734 x_scale = 1.0;
2732 y_scale = 1.0; 2735 y_scale = 1.0;
2733 x_center = (double)0.5*src.width(); 2736 x_center = (double)0.5*src.width();
2734 y_center = (double)0.5*src.height(); 2737 y_center = (double)0.5*src.height();
2735 radius=x_center; 2738 radius=x_center;
2736 if(src.width() > src.height()) 2739 if(src.width() > src.height())
2737 y_scale = (double)src.width()/src.height(); 2740 y_scale = (double)src.width()/src.height();
2738 else if(src.width() < src.height()){ 2741 else if(src.width() < src.height()){
2739 x_scale = (double) src.height()/src.width(); 2742 x_scale = (double) src.height()/src.width();
2740 radius = y_center; 2743 radius = y_center;
2741 } 2744 }
2742 amount=factor/10.0; 2745 amount=factor/10.0;
2743 if(amount >= 0) 2746 if(amount >= 0)
2744 amount/=10.0; 2747 amount/=10.0;
2745 if(src.depth() > 8){ // DirectClass source image 2748 if(src.depth() > 8){ // DirectClass source image
2746 unsigned int *srcData; 2749 unsigned int *srcData;
2747 for(y=0; y < src.height(); ++y){ 2750 for(y=0; y < src.height(); ++y){
2748 srcData = (unsigned int *)src.scanLine(y); 2751 srcData = (unsigned int *)src.scanLine(y);
2749 destData = (unsigned int *)dest.scanLine(y); 2752 destData = (unsigned int *)dest.scanLine(y);
2750 y_distance=y_scale*(y-y_center); 2753 y_distance=y_scale*(y-y_center);
2751 for(x=0; x < src.width(); ++x){ 2754 for(x=0; x < src.width(); ++x){
2752 destData[x] = srcData[x]; 2755 destData[x] = srcData[x];
2753 x_distance = x_scale*(x-x_center); 2756 x_distance = x_scale*(x-x_center);
2754 distance= x_distance*x_distance+y_distance*y_distance; 2757 distance= x_distance*x_distance+y_distance*y_distance;
2755 if(distance < (radius*radius)){ 2758 if(distance < (radius*radius)){
2756 double factor; 2759 double factor;
2757 // Implode the pixel. 2760 // Implode the pixel.
2758 factor=1.0; 2761 factor=1.0;
2759 if(distance > 0.0) 2762 if(distance > 0.0)
2760 factor= 2763 factor=
2761 pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount); 2764 pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount);
2762 destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center, 2765 destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center,
2763 factor*y_distance/y_scale+y_center, 2766 factor*y_distance/y_scale+y_center,
2764 background); 2767 background);
2765 } 2768 }
2766 } 2769 }
2767 } 2770 }
2768 } 2771 }
2769 else{ // PsudeoClass source image 2772 else{ // PsudeoClass source image
2770 unsigned char *srcData; 2773 unsigned char *srcData;
2771 unsigned char idx; 2774 unsigned char idx;
2772 unsigned int *cTable = src.colorTable(); 2775 unsigned int *cTable = src.colorTable();
2773 for(y=0; y < src.height(); ++y){ 2776 for(y=0; y < src.height(); ++y){
2774 srcData = (unsigned char *)src.scanLine(y); 2777 srcData = (unsigned char *)src.scanLine(y);
2775 destData = (unsigned int *)dest.scanLine(y); 2778 destData = (unsigned int *)dest.scanLine(y);
2776 y_distance=y_scale*(y-y_center); 2779 y_distance=y_scale*(y-y_center);
2777 for(x=0; x < src.width(); ++x){ 2780 for(x=0; x < src.width(); ++x){
2778 idx = srcData[x]; 2781 idx = srcData[x];
2779 destData[x] = cTable[idx]; 2782 destData[x] = cTable[idx];
2780 x_distance = x_scale*(x-x_center); 2783 x_distance = x_scale*(x-x_center);
2781 distance= x_distance*x_distance+y_distance*y_distance; 2784 distance= x_distance*x_distance+y_distance*y_distance;
2782 if(distance < (radius*radius)){ 2785 if(distance < (radius*radius)){
2783 double factor; 2786 double factor;
2784 // Implode the pixel. 2787 // Implode the pixel.
2785 factor=1.0; 2788 factor=1.0;
2786 if(distance > 0.0) 2789 if(distance > 0.0)
2787 factor= 2790 factor=
2788 pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount); 2791 pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount);
2789 destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center, 2792 destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center,
2790 factor*y_distance/y_scale+y_center, 2793 factor*y_distance/y_scale+y_center,
2791 background); 2794 background);
2792 } 2795 }
2793 } 2796 }
2794 } 2797 }
2795 2798
2796 } 2799 }
2797 return(dest); 2800 return(dest);
2798} 2801}
2799 2802
2800QImage OImageEffect::rotate(QImage &img, RotateDirection r) 2803QImage OImageEffect::rotate(QImage &img, RotateDirection r)
2801{ 2804{
2802 QImage dest; 2805 QImage dest;
2803 int x, y; 2806 int x, y;
2804 if(img.depth() > 8){ 2807 if(img.depth() > 8){
2805 unsigned int *srcData, *destData; 2808 unsigned int *srcData, *destData;
2806 switch(r){ 2809 switch(r){
2807 case Rotate90: 2810 case Rotate90:
2808 dest.create(img.height(), img.width(), img.depth()); 2811 dest.create(img.height(), img.width(), img.depth());
2809 for(y=0; y < img.height(); ++y){ 2812 for(y=0; y < img.height(); ++y){
2810 srcData = (unsigned int *)img.scanLine(y); 2813 srcData = (unsigned int *)img.scanLine(y);
2811 for(x=0; x < img.width(); ++x){ 2814 for(x=0; x < img.width(); ++x){
2812 destData = (unsigned int *)dest.scanLine(x); 2815 destData = (unsigned int *)dest.scanLine(x);
2813 destData[img.height()-y-1] = srcData[x]; 2816 destData[img.height()-y-1] = srcData[x];
2814 } 2817 }
2815 } 2818 }
2816 break; 2819 break;
2817 case Rotate180: 2820 case Rotate180:
2818 dest.create(img.width(), img.height(), img.depth()); 2821 dest.create(img.width(), img.height(), img.depth());
2819 for(y=0; y < img.height(); ++y){ 2822 for(y=0; y < img.height(); ++y){
2820 srcData = (unsigned int *)img.scanLine(y); 2823 srcData = (unsigned int *)img.scanLine(y);
2821 destData = (unsigned int *)dest.scanLine(img.height()-y-1); 2824 destData = (unsigned int *)dest.scanLine(img.height()-y-1);
2822 for(x=0; x < img.width(); ++x) 2825 for(x=0; x < img.width(); ++x)
2823 destData[img.width()-x-1] = srcData[x]; 2826 destData[img.width()-x-1] = srcData[x];
2824 } 2827 }
2825 break; 2828 break;
2826 case Rotate270: 2829 case Rotate270:
2827 dest.create(img.height(), img.width(), img.depth()); 2830 dest.create(img.height(), img.width(), img.depth());
2828 for(y=0; y < img.height(); ++y){ 2831 for(y=0; y < img.height(); ++y){
2829 srcData = (unsigned int *)img.scanLine(y); 2832 srcData = (unsigned int *)img.scanLine(y);
2830 for(x=0; x < img.width(); ++x){ 2833 for(x=0; x < img.width(); ++x){
2831 destData = (unsigned int *)dest.scanLine(img.width()-x-1); 2834 destData = (unsigned int *)dest.scanLine(img.width()-x-1);
2832 destData[y] = srcData[x]; 2835 destData[y] = srcData[x];
2833 } 2836 }
2834 } 2837 }
2835 break; 2838 break;
2836 default: 2839 default:
2837 dest = img; 2840 dest = img;
2838 break; 2841 break;
2839 } 2842 }
2840 } 2843 }
2841 else{ 2844 else{
2842 unsigned char *srcData, *destData; 2845 unsigned char *srcData, *destData;
2843 unsigned int *srcTable, *destTable; 2846 unsigned int *srcTable, *destTable;
2844 switch(r){ 2847 switch(r){
2845 case Rotate90: 2848 case Rotate90:
2846 dest.create(img.height(), img.width(), img.depth()); 2849 dest.create(img.height(), img.width(), img.depth());
2847 dest.setNumColors(img.numColors()); 2850 dest.setNumColors(img.numColors());
2848 srcTable = (unsigned int *)img.colorTable(); 2851 srcTable = (unsigned int *)img.colorTable();
2849 destTable = (unsigned int *)dest.colorTable(); 2852 destTable = (unsigned int *)dest.colorTable();
2850 for(x=0; x < img.numColors(); ++x) 2853 for(x=0; x < img.numColors(); ++x)
2851 destTable[x] = srcTable[x]; 2854 destTable[x] = srcTable[x];
2852 for(y=0; y < img.height(); ++y){ 2855 for(y=0; y < img.height(); ++y){
2853 srcData = (unsigned char *)img.scanLine(y); 2856 srcData = (unsigned char *)img.scanLine(y);
2854 for(x=0; x < img.width(); ++x){ 2857 for(x=0; x < img.width(); ++x){
2855 destData = (unsigned char *)dest.scanLine(x); 2858 destData = (unsigned char *)dest.scanLine(x);
2856 destData[img.height()-y-1] = srcData[x]; 2859 destData[img.height()-y-1] = srcData[x];
2857 } 2860 }
2858 } 2861 }
2859 break; 2862 break;
2860 case Rotate180: 2863 case Rotate180:
2861 dest.create(img.width(), img.height(), img.depth()); 2864 dest.create(img.width(), img.height(), img.depth());
2862 dest.setNumColors(img.numColors()); 2865 dest.setNumColors(img.numColors());
2863 srcTable = (unsigned int *)img.colorTable(); 2866 srcTable = (unsigned int *)img.colorTable();
2864 destTable = (unsigned int *)dest.colorTable(); 2867 destTable = (unsigned int *)dest.colorTable();
2865 for(x=0; x < img.numColors(); ++x) 2868 for(x=0; x < img.numColors(); ++x)
2866 destTable[x] = srcTable[x]; 2869 destTable[x] = srcTable[x];
2867 for(y=0; y < img.height(); ++y){ 2870 for(y=0; y < img.height(); ++y){
2868 srcData = (unsigned char *)img.scanLine(y); 2871 srcData = (unsigned char *)img.scanLine(y);
2869 destData = (unsigned char *)dest.scanLine(img.height()-y-1); 2872 destData = (unsigned char *)dest.scanLine(img.height()-y-1);
2870 for(x=0; x < img.width(); ++x) 2873 for(x=0; x < img.width(); ++x)
2871 destData[img.width()-x-1] = srcData[x]; 2874 destData[img.width()-x-1] = srcData[x];
2872 } 2875 }
2873 break; 2876 break;
2874 case Rotate270: 2877 case Rotate270:
2875 dest.create(img.height(), img.width(), img.depth()); 2878 dest.create(img.height(), img.width(), img.depth());
2876 dest.setNumColors(img.numColors()); 2879 dest.setNumColors(img.numColors());
2877 srcTable = (unsigned int *)img.colorTable(); 2880 srcTable = (unsigned int *)img.colorTable();
2878 destTable = (unsigned int *)dest.colorTable(); 2881 destTable = (unsigned int *)dest.colorTable();
2879 for(x=0; x < img.numColors(); ++x) 2882 for(x=0; x < img.numColors(); ++x)
2880 destTable[x] = srcTable[x]; 2883 destTable[x] = srcTable[x];
2881 for(y=0; y < img.height(); ++y){ 2884 for(y=0; y < img.height(); ++y){
2882 srcData = (unsigned char *)img.scanLine(y); 2885 srcData = (unsigned char *)img.scanLine(y);
2883 for(x=0; x < img.width(); ++x){ 2886 for(x=0; x < img.width(); ++x){
2884 destData = (unsigned char *)dest.scanLine(img.width()-x-1); 2887 destData = (unsigned char *)dest.scanLine(img.width()-x-1);
2885 destData[y] = srcData[x]; 2888 destData[y] = srcData[x];
2886 } 2889 }
2887 } 2890 }
2888 break; 2891 break;
2889 default: 2892 default:
2890 dest = img; 2893 dest = img;
2891 break; 2894 break;
2892 } 2895 }
2893 2896
2894 } 2897 }
2895 return(dest); 2898 return(dest);
2896} 2899}
2897 2900
2898void OImageEffect::solarize(QImage &img, double factor) 2901void OImageEffect::solarize(QImage &img, double factor)
2899{ 2902{
2900 int i, count; 2903 int i, count;
2901 int threshold; 2904 int threshold;
2902 unsigned int *data; 2905 unsigned int *data;
2903 2906
2904 threshold = (int)(factor*(MaxRGB+1)/100.0); 2907 threshold = (int)(factor*(MaxRGB+1)/100.0);
2905 if(img.depth() < 32){ 2908 if(img.depth() < 32){
2906 data = (unsigned int *)img.colorTable(); 2909 data = (unsigned int *)img.colorTable();
2907 count = img.numColors(); 2910 count = img.numColors();
2908 } 2911 }
2909 else{ 2912 else{
2910 data = (unsigned int *)img.bits(); 2913 data = (unsigned int *)img.bits();
2911 count = img.width()*img.height(); 2914 count = img.width()*img.height();
2912 } 2915 }
2913 for(i=0; i < count; ++i){ 2916 for(i=0; i < count; ++i){
2914 data[i] = qRgba(qRed(data[i]) > threshold ? MaxRGB-qRed(data[i]) : qRed(data[i]), 2917 data[i] = qRgba(qRed(data[i]) > threshold ? MaxRGB-qRed(data[i]) : qRed(data[i]),
2915 qGreen(data[i]) > threshold ? MaxRGB-qGreen(data[i]) : qGreen(data[i]), 2918 qGreen(data[i]) > threshold ? MaxRGB-qGreen(data[i]) : qGreen(data[i]),
2916 qBlue(data[i]) > threshold ? MaxRGB-qBlue(data[i]) : qBlue(data[i]), 2919 qBlue(data[i]) > threshold ? MaxRGB-qBlue(data[i]) : qBlue(data[i]),
2917 qAlpha(data[i])); 2920 qAlpha(data[i]));
2918 } 2921 }
2919} 2922}
2920 2923
2921QImage OImageEffect::spread(QImage &src, unsigned int amount) 2924QImage OImageEffect::spread(QImage &src, unsigned int amount)
2922{ 2925{
2923 int quantum, x, y; 2926 int quantum, x, y;
2924 int x_distance, y_distance; 2927 int x_distance, y_distance;
2925 if(src.width() < 3 || src.height() < 3) 2928 if(src.width() < 3 || src.height() < 3)
2926 return(src); 2929 return(src);
2927 QImage dest(src); 2930 QImage dest(src);
2928 dest.detach(); 2931 dest.detach();
2929 quantum=(amount+1) >> 1; 2932 quantum=(amount+1) >> 1;
2930 if(src.depth() > 8){ // DirectClass source image 2933 if(src.depth() > 8){ // DirectClass source image
2931 unsigned int *p, *q; 2934 unsigned int *p, *q;
2932 for(y=0; y < src.height(); y++){ 2935 for(y=0; y < src.height(); y++){
2933 q = (unsigned int *)dest.scanLine(y); 2936 q = (unsigned int *)dest.scanLine(y);
2934 for(x=0; x < src.width(); x++){ 2937 for(x=0; x < src.width(); x++){
2935 x_distance = x + ((rand() & (amount+1))-quantum); 2938 x_distance = x + ((rand() & (amount+1))-quantum);
2936 y_distance = y + ((rand() & (amount+1))-quantum); 2939 y_distance = y + ((rand() & (amount+1))-quantum);
2937 x_distance = QMIN(x_distance, src.width()-1); 2940 x_distance = QMIN(x_distance, src.width()-1);
2938 y_distance = QMIN(y_distance, src.height()-1); 2941 y_distance = QMIN(y_distance, src.height()-1);
2939 if(x_distance < 0) 2942 if(x_distance < 0)
2940 x_distance = 0; 2943 x_distance = 0;
2941 if(y_distance < 0) 2944 if(y_distance < 0)
2942 y_distance = 0; 2945 y_distance = 0;
2943 p = (unsigned int *)src.scanLine(y_distance); 2946 p = (unsigned int *)src.scanLine(y_distance);
2944 p += x_distance; 2947 p += x_distance;
2945 *q++=(*p); 2948 *q++=(*p);
2946 } 2949 }
2947 } 2950 }
2948 } 2951 }
2949 else{ // PsudeoClass source image 2952 else{ // PsudeoClass source image
2950 // just do colortable values 2953 // just do colortable values
2951 unsigned char *p, *q; 2954 unsigned char *p, *q;
2952 for(y=0; y < src.height(); y++){ 2955 for(y=0; y < src.height(); y++){
2953 q = (unsigned char *)dest.scanLine(y); 2956 q = (unsigned char *)dest.scanLine(y);
2954 for(x=0; x < src.width(); x++){ 2957 for(x=0; x < src.width(); x++){
2955 x_distance = x + ((rand() & (amount+1))-quantum); 2958 x_distance = x + ((rand() & (amount+1))-quantum);
2956 y_distance = y + ((rand() & (amount+1))-quantum); 2959 y_distance = y + ((rand() & (amount+1))-quantum);
2957 x_distance = QMIN(x_distance, src.width()-1); 2960 x_distance = QMIN(x_distance, src.width()-1);
2958 y_distance = QMIN(y_distance, src.height()-1); 2961 y_distance = QMIN(y_distance, src.height()-1);
2959 if(x_distance < 0) 2962 if(x_distance < 0)
2960 x_distance = 0; 2963 x_distance = 0;
2961 if(y_distance < 0) 2964 if(y_distance < 0)
2962 y_distance = 0; 2965 y_distance = 0;
2963 p = (unsigned char *)src.scanLine(y_distance); 2966 p = (unsigned char *)src.scanLine(y_distance);
2964 p += x_distance; 2967 p += x_distance;
2965 *q++=(*p); 2968 *q++=(*p);
2966 } 2969 }
2967 } 2970 }
2968 } 2971 }
2969 return(dest); 2972 return(dest);
2970} 2973}
2971 2974
2972QImage OImageEffect::swirl(QImage &src, double degrees, 2975QImage OImageEffect::swirl(QImage &src, double degrees,
2973 unsigned int background) 2976 unsigned int background)
2974{ 2977{
2975 double cosine, distance, factor, radius, sine, x_center, x_distance, 2978 double cosine, distance, factor, radius, sine, x_center, x_distance,
2976 x_scale, y_center, y_distance, y_scale; 2979 x_scale, y_center, y_distance, y_scale;
2977 int x, y; 2980 int x, y;
2978 unsigned int *q; 2981 unsigned int *q;
2979 QImage dest(src.width(), src.height(), 32); 2982 QImage dest(src.width(), src.height(), 32);
2980 2983
2981 // compute scaling factor 2984 // compute scaling factor
2982 x_center = src.width()/2.0; 2985 x_center = src.width()/2.0;
2983 y_center = src.height()/2.0; 2986 y_center = src.height()/2.0;
2984 radius = QMAX(x_center,y_center); 2987 radius = QMAX(x_center,y_center);
2985 x_scale=1.0; 2988 x_scale=1.0;
2986 y_scale=1.0; 2989 y_scale=1.0;
2987 if(src.width() > src.height()) 2990 if(src.width() > src.height())
2988 y_scale=(double)src.width()/src.height(); 2991 y_scale=(double)src.width()/src.height();
2989 else if(src.width() < src.height()) 2992 else if(src.width() < src.height())
2990 x_scale=(double)src.height()/src.width(); 2993 x_scale=(double)src.height()/src.width();
2991 degrees=DegreesToRadians(degrees); 2994 degrees=DegreesToRadians(degrees);
2992 // swirl each row 2995 // swirl each row
2993 if(src.depth() > 8){ // DirectClass source image 2996 if(src.depth() > 8){ // DirectClass source image
2994 unsigned int *p; 2997 unsigned int *p;
2995 for(y=0; y < src.height(); y++){ 2998 for(y=0; y < src.height(); y++){
2996 p = (unsigned int *)src.scanLine(y); 2999 p = (unsigned int *)src.scanLine(y);
2997 q = (unsigned int *)dest.scanLine(y); 3000 q = (unsigned int *)dest.scanLine(y);
2998 y_distance = y_scale*(y-y_center); 3001 y_distance = y_scale*(y-y_center);
2999 for(x=0; x < src.width(); x++){ 3002 for(x=0; x < src.width(); x++){
3000 // determine if the pixel is within an ellipse 3003 // determine if the pixel is within an ellipse
3001 *q=(*p); 3004 *q=(*p);
3002 x_distance = x_scale*(x-x_center); 3005 x_distance = x_scale*(x-x_center);
3003 distance = x_distance*x_distance+y_distance*y_distance; 3006 distance = x_distance*x_distance+y_distance*y_distance;
3004 if (distance < (radius*radius)){ 3007 if (distance < (radius*radius)){
3005 // swirl 3008 // swirl
3006 factor = 1.0-sqrt(distance)/radius; 3009 factor = 1.0-sqrt(distance)/radius;
3007 sine = sin(degrees*factor*factor); 3010 sine = sin(degrees*factor*factor);
3008 cosine = cos(degrees*factor*factor); 3011 cosine = cos(degrees*factor*factor);
3009 *q = interpolateColor(&src, 3012 *q = interpolateColor(&src,
3010 (cosine*x_distance-sine*y_distance)/x_scale+x_center, 3013 (cosine*x_distance-sine*y_distance)/x_scale+x_center,
3011 (sine*x_distance+cosine*y_distance)/y_scale+y_center, 3014 (sine*x_distance+cosine*y_distance)/y_scale+y_center,
3012 background); 3015 background);
3013 } 3016 }
3014 p++; 3017 p++;
3015 q++; 3018 q++;
3016 } 3019 }
3017 } 3020 }
3018 } 3021 }
3019 else{ // PsudeoClass source image 3022 else{ // PsudeoClass source image
3020 unsigned char *p; 3023 unsigned char *p;
3021 unsigned int *cTable = (unsigned int *)src.colorTable(); 3024 unsigned int *cTable = (unsigned int *)src.colorTable();
3022 for(y=0; y < src.height(); y++){ 3025 for(y=0; y < src.height(); y++){
3023 p = (unsigned char *)src.scanLine(y); 3026 p = (unsigned char *)src.scanLine(y);
3024 q = (unsigned int *)dest.scanLine(y); 3027 q = (unsigned int *)dest.scanLine(y);
3025 y_distance = y_scale*(y-y_center); 3028 y_distance = y_scale*(y-y_center);
3026 for(x=0; x < src.width(); x++){ 3029 for(x=0; x < src.width(); x++){
3027 // determine if the pixel is within an ellipse 3030 // determine if the pixel is within an ellipse
3028 *q = *(cTable+(*p)); 3031 *q = *(cTable+(*p));
3029 x_distance = x_scale*(x-x_center); 3032 x_distance = x_scale*(x-x_center);
3030 distance = x_distance*x_distance+y_distance*y_distance; 3033 distance = x_distance*x_distance+y_distance*y_distance;
3031 if (distance < (radius*radius)){ 3034 if (distance < (radius*radius)){
3032 // swirl 3035 // swirl
3033 factor = 1.0-sqrt(distance)/radius; 3036 factor = 1.0-sqrt(distance)/radius;
3034 sine = sin(degrees*factor*factor); 3037 sine = sin(degrees*factor*factor);
3035 cosine = cos(degrees*factor*factor); 3038 cosine = cos(degrees*factor*factor);
3036 *q = interpolateColor(&src, 3039 *q = interpolateColor(&src,
3037 (cosine*x_distance-sine*y_distance)/x_scale+x_center, 3040 (cosine*x_distance-sine*y_distance)/x_scale+x_center,
3038 (sine*x_distance+cosine*y_distance)/y_scale+y_center, 3041 (sine*x_distance+cosine*y_distance)/y_scale+y_center,
3039 background); 3042 background);
3040 } 3043 }
3041 p++; 3044 p++;
3042 q++; 3045 q++;
3043 } 3046 }
3044 } 3047 }
3045 3048
3046 } 3049 }
3047 return(dest); 3050 return(dest);
3048} 3051}
3049 3052
3050QImage OImageEffect::wave(QImage &src, double amplitude, double wavelength, 3053QImage OImageEffect::wave(QImage &src, double amplitude, double wavelength,
3051 unsigned int background) 3054 unsigned int background)
3052{ 3055{
3053 double *sine_map; 3056 double *sine_map;
3054 int x, y; 3057 int x, y;
3055 unsigned int *q; 3058 unsigned int *q;
3056 3059
3057 QImage dest(src.width(), src.height() + (int)(2*fabs(amplitude)), 32); 3060 QImage dest(src.width(), src.height() + (int)(2*fabs(amplitude)), 32);
3058 // allocate sine map 3061 // allocate sine map
3059 sine_map = (double *)malloc(dest.width()*sizeof(double)); 3062 sine_map = (double *)malloc(dest.width()*sizeof(double));
3060 if(!sine_map) 3063 if(!sine_map)
3061 return(src); 3064 return(src);
3062 for(x=0; x < dest.width(); ++x) 3065 for(x=0; x < dest.width(); ++x)
3063 sine_map[x]=fabs(amplitude)+amplitude*sin((2*M_PI*x)/wavelength); 3066 sine_map[x]=fabs(amplitude)+amplitude*sin((2*M_PI*x)/wavelength);
3064 // wave image 3067 // wave image
3065 for(y=0; y < dest.height(); ++y){ 3068 for(y=0; y < dest.height(); ++y){
3066 q = (unsigned int *)dest.scanLine(y); 3069 q = (unsigned int *)dest.scanLine(y);
3067 for (x=0; x < dest.width(); x++){ 3070 for (x=0; x < dest.width(); x++){
3068 *q=interpolateColor(&src, x, (int)(y-sine_map[x]), background); 3071 *q=interpolateColor(&src, x, (int)(y-sine_map[x]), background);
3069 ++q; 3072 ++q;
3070 } 3073 }
3071 } 3074 }
3072 free(sine_map); 3075 free(sine_map);
3073 return(dest); 3076 return(dest);
3074} 3077}
3075 3078
3076QImage OImageEffect::oilPaint(QImage &src, int radius) 3079QImage OImageEffect::oilPaint(QImage &src, int radius)
3077{ 3080{
3078 // TODO 8bpp src! 3081 // TODO 8bpp src!
3079 if(src.depth() < 32){ 3082 if(src.depth() < 32){
3080 owarn << "Oil Paint source image < 32bpp. Convert before using!" << oendl; 3083 owarn << "Oil Paint source image < 32bpp. Convert before using!" << oendl;
3081 return(src); 3084 return(src);
3082 } 3085 }
3083 int j, k, i, x, y; 3086 int j, k, i, x, y;
3084 unsigned int *histogram; 3087 unsigned int *histogram;
3085 unsigned int *s; 3088 unsigned int *s;
3086 unsigned int count; 3089 unsigned int count;
3087 3090
3088 unsigned int *srcData, *destData; 3091 unsigned int *srcData, *destData;
3089 3092
3090 QImage dest(src); 3093 QImage dest(src);
3091 dest.detach(); 3094 dest.detach();
3092 histogram = (unsigned int *) malloc((MaxRGB+1)*sizeof(unsigned int)); 3095 histogram = (unsigned int *) malloc((MaxRGB+1)*sizeof(unsigned int));
3093 if(!histogram) 3096 if(!histogram)
3094 return(src); 3097 return(src);
3095 // paint each row 3098 // paint each row
3096 k=0; 3099 k=0;
3097 for(y = radius; y < src.height(); ++y){ 3100 for(y = radius; y < src.height(); ++y){
3098 srcData = (unsigned int *)src.scanLine(y-radius); 3101 srcData = (unsigned int *)src.scanLine(y-radius);
3099 destData = (unsigned int *)dest.scanLine(y); 3102 destData = (unsigned int *)dest.scanLine(y);
3100 srcData += radius*src.width()+radius; 3103 srcData += radius*src.width()+radius;
3101 destData += radius; 3104 destData += radius;
3102 for(x=radius; x < src.width()-radius; ++x){ 3105 for(x=radius; x < src.width()-radius; ++x){
3103 // determine most frequent color 3106 // determine most frequent color
3104 count = 0; 3107 count = 0;
3105 for(i=0; i < MaxRGB+1; ++i) 3108 for(i=0; i < MaxRGB+1; ++i)
3106 histogram[i] = 0; 3109 histogram[i] = 0;
3107 for(i=0; i < radius; ++i){ 3110 for(i=0; i < radius; ++i){
3108 s = srcData-(radius-1)*src.width()-i-1; 3111 s = srcData-(radius-1)*src.width()-i-1;
3109 for(j =0; j < (2*i+1); ++j){ 3112 for(j =0; j < (2*i+1); ++j){
3110 k = intensityValue(*s); 3113 k = intensityValue(*s);
3111 histogram[k]++; 3114 histogram[k]++;
3112 if(histogram[k] > count){ 3115 if(histogram[k] > count){
3113 *destData = *s; 3116 *destData = *s;
3114 count = histogram[k]; 3117 count = histogram[k];
3115 } 3118 }
3116 ++s; 3119 ++s;
3117 } 3120 }
3118 s = srcData+(radius-i)*src.width()-i-1; 3121 s = srcData+(radius-i)*src.width()-i-1;
3119 for(j =0; j < (2*i+1); ++j){ 3122 for(j =0; j < (2*i+1); ++j){
3120 k = intensityValue(*s); 3123 k = intensityValue(*s);
3121 histogram[k]++; 3124 histogram[k]++;
3122 if(histogram[k] > count){ 3125 if(histogram[k] > count){
3123 *destData = *s; 3126 *destData = *s;
3124 count = histogram[k]; 3127 count = histogram[k];
3125 } 3128 }
3126 ++s; 3129 ++s;
3127 } 3130 }
3128 } 3131 }
3129 s = srcData-radius; 3132 s = srcData-radius;
3130 for(j =0; j < (2*i+1); ++j){ 3133 for(j =0; j < (2*i+1); ++j){
3131 k = intensityValue(*s); 3134 k = intensityValue(*s);
3132 histogram[k]++; 3135 histogram[k]++;
3133 if(histogram[k] > count){ 3136 if(histogram[k] > count){
3134 *destData = *s; 3137 *destData = *s;
3135 count = histogram[k]; 3138 count = histogram[k];
3136 } 3139 }
3137 ++s; 3140 ++s;
3138 } 3141 }
3139 ++srcData; 3142 ++srcData;
3140 ++destData; 3143 ++destData;
3141 } 3144 }
3142 } 3145 }
3143 free(histogram); 3146 free(histogram);
3144 return(dest); 3147 return(dest);
3145} 3148}
3146 3149
3147// 3150//
3148// The following methods work by computing a value from neighboring pixels 3151// The following methods work by computing a value from neighboring pixels
3149// (mosfet 12/28/01) 3152// (mosfet 12/28/01)
3150// 3153//
3151 3154
3152QImage OImageEffect::edge(QImage &src, double factor) 3155QImage OImageEffect::edge(QImage &src, double factor)
3153{ 3156{
3154#define Edge(weight) \ 3157#define Edge(weight) \
3155 total_red+=(weight)*qRed(*s); \ 3158 total_red+=(weight)*qRed(*s); \
3156 total_green+=(weight)*qGreen(*s); \ 3159 total_green+=(weight)*qGreen(*s); \
3157 total_blue+=(weight)*qBlue(*s); \ 3160 total_blue+=(weight)*qBlue(*s); \
3158 total_opacity+=(weight)*qAlpha(*s); \ 3161 total_opacity+=(weight)*qAlpha(*s); \
3159 s++; 3162 s++;
3160 3163
3161#define Edge256(weight) \ 3164#define Edge256(weight) \
3162 total_red+=(weight)*qRed(*(cTable+(*s))); \ 3165 total_red+=(weight)*qRed(*(cTable+(*s))); \
3163 total_green+=(weight)*qGreen(*(cTable+(*s))); \ 3166 total_green+=(weight)*qGreen(*(cTable+(*s))); \
3164 total_blue+=(weight)*qBlue(*(cTable+(*s))); \ 3167 total_blue+=(weight)*qBlue(*(cTable+(*s))); \
3165 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \ 3168 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \
3166 s++; 3169 s++;
3167 3170
3168 if(src.width() < 3 || src.height() < 3) 3171 if(src.width() < 3 || src.height() < 3)
3169 return(src); 3172 return(src);
3170 3173
3171 double total_blue, total_green, total_opacity, total_red, weight; 3174 double total_blue, total_green, total_opacity, total_red, weight;
3172 3175
3173 int x, y; 3176 int x, y;
3174 3177
3175 unsigned int *q; 3178 unsigned int *q;
3176 3179
3177 QImage dest(src.width(), src.height(), 32); 3180 QImage dest(src.width(), src.height(), 32);
3178 weight=factor/8.0; 3181 weight=factor/8.0;
3179 if(src.depth() > 8){ // DirectClass source image 3182 if(src.depth() > 8){ // DirectClass source image
3180 unsigned int *p, *s; 3183 unsigned int *p, *s;
3181 for(y=0; y < src.height(); ++y){ 3184 for(y=0; y < src.height(); ++y){
3182 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); 3185 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3));
3183 q = (unsigned int *)dest.scanLine(y); 3186 q = (unsigned int *)dest.scanLine(y);
3184 // edge detect this row of pixels. 3187 // edge detect this row of pixels.
3185 *q++=(*(p+src.width())); 3188 *q++=(*(p+src.width()));
3186 for(x=1; x < src.width()-1; ++x){ 3189 for(x=1; x < src.width()-1; ++x){
3187 // compute weighted average of target pixel color components. 3190 // compute weighted average of target pixel color components.
3188 total_red=0.0; 3191 total_red=0.0;
3189 total_green=0.0; 3192 total_green=0.0;
3190 total_blue=0.0; 3193 total_blue=0.0;
3191 total_opacity=0.0; 3194 total_opacity=0.0;
3192 s=p; 3195 s=p;
3193 Edge(-weight/8); Edge(-weight/8) Edge(-weight/8); 3196 Edge(-weight/8); Edge(-weight/8) Edge(-weight/8);
3194 s=p+src.width(); 3197 s=p+src.width();
3195 Edge(-weight/8); Edge(weight); Edge(-weight/8); 3198 Edge(-weight/8); Edge(weight); Edge(-weight/8);
3196 s=p+2*src.width(); 3199 s=p+2*src.width();
3197 Edge(-weight/8); Edge(-weight/8); Edge(-weight/8); 3200 Edge(-weight/8); Edge(-weight/8); Edge(-weight/8);
3198 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red), 3201 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red),
3199 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green), 3202 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green),
3200 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue), 3203 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue),
3201 (unsigned char)((total_opacity < 0) ? 0 : (total_opacity > MaxRGB) ? MaxRGB : total_opacity)); 3204 (unsigned char)((total_opacity < 0) ? 0 : (total_opacity > MaxRGB) ? MaxRGB : total_opacity));
3202 p++; 3205 p++;
3203 q++; 3206 q++;
3204 } 3207 }
3205 p++; 3208 p++;
3206 *q++=(*p); 3209 *q++=(*p);
3207 } 3210 }
3208 } 3211 }
3209 else{ // PsudeoClass source image 3212 else{ // PsudeoClass source image
3210 unsigned char *p, *p2, *p3, *s; 3213 unsigned char *p, *p2, *p3, *s;
3211 unsigned int *cTable = src.colorTable(); 3214 unsigned int *cTable = src.colorTable();
3212 int scanLineIdx; 3215 int scanLineIdx;
3213 for(y=0; y < src.height(); ++y){ 3216 for(y=0; y < src.height(); ++y){
3214 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); 3217 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3);
3215 p = (unsigned char *)src.scanLine(scanLineIdx); 3218 p = (unsigned char *)src.scanLine(scanLineIdx);
3216 p2 = (unsigned char *)src.scanLine(scanLineIdx+1); 3219 p2 = (unsigned char *)src.scanLine(scanLineIdx+1);
3217 p3 = (unsigned char *)src.scanLine(scanLineIdx+2); 3220 p3 = (unsigned char *)src.scanLine(scanLineIdx+2);
3218 q = (unsigned int *)dest.scanLine(y); 3221 q = (unsigned int *)dest.scanLine(y);
3219 // edge detect this row of pixels. 3222 // edge detect this row of pixels.
3220 *q++=(*(cTable+(*p2))); 3223 *q++=(*(cTable+(*p2)));
3221 for(x=1; x < src.width()-1; ++x){ 3224 for(x=1; x < src.width()-1; ++x){
3222 // compute weighted average of target pixel color components. 3225 // compute weighted average of target pixel color components.
3223 total_red=0.0; 3226 total_red=0.0;
3224 total_green=0.0; 3227 total_green=0.0;
3225 total_blue=0.0; 3228 total_blue=0.0;
3226 total_opacity=0.0; 3229 total_opacity=0.0;
3227 s=p; 3230 s=p;
3228 Edge256(-weight/8); Edge256(-weight/8) Edge256(-weight/8); 3231 Edge256(-weight/8); Edge256(-weight/8) Edge256(-weight/8);
3229 s=p2; 3232 s=p2;
3230 Edge256(-weight/8); Edge256(weight); Edge256(-weight/8); 3233 Edge256(-weight/8); Edge256(weight); Edge256(-weight/8);
3231 s=p3; 3234 s=p3;
3232 Edge256(-weight/8); Edge256(-weight/8); Edge256(-weight/8); 3235 Edge256(-weight/8); Edge256(-weight/8); Edge256(-weight/8);
3233 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red), 3236 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red),
3234 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green), 3237 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green),
3235 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue), 3238 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue),
3236 (unsigned char)((total_opacity < 0) ? 0 : (total_opacity > MaxRGB) ? MaxRGB : total_opacity)); 3239 (unsigned char)((total_opacity < 0) ? 0 : (total_opacity > MaxRGB) ? MaxRGB : total_opacity));
3237 p++; 3240 p++;
3238 p2++; 3241 p2++;
3239 p3++; 3242 p3++;
3240 q++; 3243 q++;
3241 } 3244 }
3242 p++; 3245 p++;
3243 *q++=(*(cTable+(*p))); 3246 *q++=(*(cTable+(*p)));
3244 } 3247 }
3245 } 3248 }
3246 return(dest); 3249 return(dest);
3247} 3250}
3248 3251
3249QImage OImageEffect::sharpen(QImage &src, double factor) 3252QImage OImageEffect::sharpen(QImage &src, double factor)
3250{ 3253{
3251#define Sharpen(weight) \ 3254#define Sharpen(weight) \
3252 total_red+=(weight)*qRed(*s); \ 3255 total_red+=(weight)*qRed(*s); \
3253 total_green+=(weight)*qGreen(*s); \ 3256 total_green+=(weight)*qGreen(*s); \
3254 total_blue+=(weight)*qBlue(*s); \ 3257 total_blue+=(weight)*qBlue(*s); \
3255 total_opacity+=(weight)*qAlpha(*s); \ 3258 total_opacity+=(weight)*qAlpha(*s); \
3256 s++; 3259 s++;
3257 3260
3258#define Sharpen256(weight) \ 3261#define Sharpen256(weight) \
3259 total_red+=(weight)*qRed(*(cTable+(*s))); \ 3262 total_red+=(weight)*qRed(*(cTable+(*s))); \
3260 total_green+=(weight)*qGreen(*(cTable+(*s))); \ 3263 total_green+=(weight)*qGreen(*(cTable+(*s))); \
3261 total_blue+=(weight)*qBlue(*(cTable+(*s))); \ 3264 total_blue+=(weight)*qBlue(*(cTable+(*s))); \
3262 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \ 3265 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \
3263 s++; 3266 s++;
3264 3267
3265 if(src.width() < 3 || src.height() < 3) 3268 if(src.width() < 3 || src.height() < 3)
3266 return(src); 3269 return(src);
3267 3270
3268 double total_blue, total_green, total_opacity, total_red; 3271 double total_blue, total_green, total_opacity, total_red;
3269 double quantum, weight; 3272 double quantum, weight;
3270 unsigned char r, g, b, a; 3273 unsigned char r, g, b, a;
3271 3274
3272 int x, y; 3275 int x, y;
3273 unsigned int *q; 3276 unsigned int *q;
3274 3277
3275 QImage dest(src.width(), src.height(), 32); 3278 QImage dest(src.width(), src.height(), 32);
3276 weight = ((100.0-factor)/2.0+13.0); 3279 weight = ((100.0-factor)/2.0+13.0);
3277 quantum = QMAX(weight-12.0, 1.0); 3280 quantum = QMAX(weight-12.0, 1.0);
3278 if(src.depth() > 8){ // DirectClass source image 3281 if(src.depth() > 8){ // DirectClass source image
3279 unsigned int *p, *s; 3282 unsigned int *p, *s;
3280 for(y=0; y < src.height(); ++y){ 3283 for(y=0; y < src.height(); ++y){
3281 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); 3284 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3));
3282 q = (unsigned int *)dest.scanLine(y); 3285 q = (unsigned int *)dest.scanLine(y);
3283 // sharpen this row of pixels. 3286 // sharpen this row of pixels.
3284 *q++=(*(p+src.width())); 3287 *q++=(*(p+src.width()));
3285 for(x=1; x < src.width()-1; ++x){ 3288 for(x=1; x < src.width()-1; ++x){
3286 // compute weighted average of target pixel color components. 3289 // compute weighted average of target pixel color components.
3287 total_red=0.0; 3290 total_red=0.0;
3288 total_green=0.0; 3291 total_green=0.0;
3289 total_blue=0.0; 3292 total_blue=0.0;
3290 total_opacity=0.0; 3293 total_opacity=0.0;
3291 s=p; 3294 s=p;
3292 Sharpen(-1); Sharpen(-2); Sharpen(-1); 3295 Sharpen(-1); Sharpen(-2); Sharpen(-1);
3293 s=p+src.width(); 3296 s=p+src.width();
3294 Sharpen(-2); Sharpen(weight); Sharpen(-2); 3297 Sharpen(-2); Sharpen(weight); Sharpen(-2);
3295 s=p+2*src.width(); 3298 s=p+2*src.width();
3296 Sharpen(-1); Sharpen(-2); Sharpen(-1); 3299 Sharpen(-1); Sharpen(-2); Sharpen(-1);
3297 if(total_red < 0) 3300 if(total_red < 0)
3298 r=0; 3301 r=0;
3299 else if(total_red > (int)(MaxRGB*quantum)) 3302 else if(total_red > (int)(MaxRGB*quantum))
3300 r = (unsigned char)MaxRGB; 3303 r = (unsigned char)MaxRGB;
3301 else 3304 else
3302 r = (unsigned char)((total_red+(quantum/2.0))/quantum); 3305 r = (unsigned char)((total_red+(quantum/2.0))/quantum);
3303 3306
3304 if(total_green < 0) 3307 if(total_green < 0)
3305 g = 0; 3308 g = 0;
3306 else if(total_green > (int)(MaxRGB*quantum)) 3309 else if(total_green > (int)(MaxRGB*quantum))
3307 g = (unsigned char)MaxRGB; 3310 g = (unsigned char)MaxRGB;
3308 else 3311 else
3309 g = (unsigned char)((total_green+(quantum/2.0))/quantum); 3312 g = (unsigned char)((total_green+(quantum/2.0))/quantum);
3310 3313
3311 if(total_blue < 0) 3314 if(total_blue < 0)
3312 b = 0; 3315 b = 0;
3313 else if(total_blue > (int)(MaxRGB*quantum)) 3316 else if(total_blue > (int)(MaxRGB*quantum))
3314 b = (unsigned char)MaxRGB; 3317 b = (unsigned char)MaxRGB;
3315 else 3318 else
3316 b = (unsigned char)((total_blue+(quantum/2.0))/quantum); 3319 b = (unsigned char)((total_blue+(quantum/2.0))/quantum);
3317 3320
3318 if(total_opacity < 0) 3321 if(total_opacity < 0)
3319 a = 0; 3322 a = 0;
3320 else if(total_opacity > (int)(MaxRGB*quantum)) 3323 else if(total_opacity > (int)(MaxRGB*quantum))
3321 a = (unsigned char)MaxRGB; 3324 a = (unsigned char)MaxRGB;
3322 else 3325 else
3323 a= (unsigned char)((total_opacity+(quantum/2.0))/quantum); 3326 a= (unsigned char)((total_opacity+(quantum/2.0))/quantum);
3324 3327
3325 *q = qRgba(r, g, b, a); 3328 *q = qRgba(r, g, b, a);
3326 3329
3327 p++; 3330 p++;
3328 q++; 3331 q++;
3329 } 3332 }
3330 p++; 3333 p++;
3331 *q++=(*p); 3334 *q++=(*p);
3332 } 3335 }
3333 } 3336 }
3334 else{ // PsudeoClass source image 3337 else{ // PsudeoClass source image
3335 unsigned char *p, *p2, *p3, *s; 3338 unsigned char *p, *p2, *p3, *s;
3336 unsigned int *cTable = src.colorTable(); 3339 unsigned int *cTable = src.colorTable();
3337 int scanLineIdx; 3340 int scanLineIdx;
3338 for(y=0; y < src.height(); ++y){ 3341 for(y=0; y < src.height(); ++y){
3339 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); 3342 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3);
3340 p = (unsigned char *)src.scanLine(scanLineIdx); 3343 p = (unsigned char *)src.scanLine(scanLineIdx);
3341 p2 = (unsigned char *)src.scanLine(scanLineIdx+1); 3344 p2 = (unsigned char *)src.scanLine(scanLineIdx+1);
3342 p3 = (unsigned char *)src.scanLine(scanLineIdx+2); 3345 p3 = (unsigned char *)src.scanLine(scanLineIdx+2);
3343 q = (unsigned int *)dest.scanLine(y); 3346 q = (unsigned int *)dest.scanLine(y);
3344 // sharpen this row of pixels. 3347 // sharpen this row of pixels.
3345 *q++=(*(cTable+(*p2))); 3348 *q++=(*(cTable+(*p2)));
3346 for(x=1; x < src.width()-1; ++x){ 3349 for(x=1; x < src.width()-1; ++x){
3347 // compute weighted average of target pixel color components. 3350 // compute weighted average of target pixel color components.
3348 total_red=0.0; 3351 total_red=0.0;
3349 total_green=0.0; 3352 total_green=0.0;
3350 total_blue=0.0; 3353 total_blue=0.0;
3351 total_opacity=0.0; 3354 total_opacity=0.0;
3352 s=p; 3355 s=p;
3353 Sharpen256(-1); Sharpen256(-2); Sharpen256(-1); 3356 Sharpen256(-1); Sharpen256(-2); Sharpen256(-1);
3354 s=p2; 3357 s=p2;
3355 Sharpen256(-2); Sharpen256(weight); Sharpen256(-2); 3358 Sharpen256(-2); Sharpen256(weight); Sharpen256(-2);
3356 s=p3; 3359 s=p3;
3357 Sharpen256(-1); Sharpen256(-2); Sharpen256(-1); 3360 Sharpen256(-1); Sharpen256(-2); Sharpen256(-1);
3358 if(total_red < 0) 3361 if(total_red < 0)
3359 r=0; 3362 r=0;
3360 else if(total_red > (int)(MaxRGB*quantum)) 3363 else if(total_red > (int)(MaxRGB*quantum))
3361 r = (unsigned char)MaxRGB; 3364 r = (unsigned char)MaxRGB;
3362 else 3365 else
3363 r = (unsigned char)((total_red+(quantum/2.0))/quantum); 3366 r = (unsigned char)((total_red+(quantum/2.0))/quantum);
3364 3367
3365 if(total_green < 0) 3368 if(total_green < 0)
3366 g = 0; 3369 g = 0;
3367 else if(total_green > (int)(MaxRGB*quantum)) 3370 else if(total_green > (int)(MaxRGB*quantum))
3368 g = (unsigned char)MaxRGB; 3371 g = (unsigned char)MaxRGB;
3369 else 3372 else
3370 g = (unsigned char)((total_green+(quantum/2.0))/quantum); 3373 g = (unsigned char)((total_green+(quantum/2.0))/quantum);
3371 3374
3372 if(total_blue < 0) 3375 if(total_blue < 0)
3373 b = 0; 3376 b = 0;
3374 else if(total_blue > (int)(MaxRGB*quantum)) 3377 else if(total_blue > (int)(MaxRGB*quantum))
3375 b = (unsigned char)MaxRGB; 3378 b = (unsigned char)MaxRGB;
3376 else 3379 else
3377 b = (unsigned char)((total_blue+(quantum/2.0))/quantum); 3380 b = (unsigned char)((total_blue+(quantum/2.0))/quantum);
3378 3381
3379 if(total_opacity < 0) 3382 if(total_opacity < 0)
3380 a = 0; 3383 a = 0;
3381 else if(total_opacity > (int)(MaxRGB*quantum)) 3384 else if(total_opacity > (int)(MaxRGB*quantum))
3382 a = (unsigned char)MaxRGB; 3385 a = (unsigned char)MaxRGB;
3383 else 3386 else
3384 a = (unsigned char)((total_opacity+(quantum/2.0))/quantum); 3387 a = (unsigned char)((total_opacity+(quantum/2.0))/quantum);
3385 3388
3386 *q = qRgba(r, g, b, a); 3389 *q = qRgba(r, g, b, a);
3387 3390
3388 p++; 3391 p++;
3389 p2++; 3392 p2++;
3390 p3++; 3393 p3++;
3391 q++; 3394 q++;
3392 } 3395 }
3393 p++; 3396 p++;
3394 *q++=(*(cTable+(*p))); 3397 *q++=(*(cTable+(*p)));
3395 } 3398 }
3396 } 3399 }
3397 return(dest); 3400 return(dest);
3398} 3401}
3399 3402
3400QImage OImageEffect::emboss(QImage &src) 3403QImage OImageEffect::emboss(QImage &src)
3401{ 3404{
3402#define Emboss(weight) \ 3405#define Emboss(weight) \
3403 total_red+=(weight)*qRed(*s); \ 3406 total_red+=(weight)*qRed(*s); \
3404 total_green+=(weight)*qGreen(*s); \ 3407 total_green+=(weight)*qGreen(*s); \
3405 total_blue+=(weight)*qBlue(*s); \ 3408 total_blue+=(weight)*qBlue(*s); \
3406 s++; 3409 s++;
3407 3410
3408#define Emboss256(weight) \ 3411#define Emboss256(weight) \
3409 total_red+=(weight)*qRed(*(cTable+(*s))); \ 3412 total_red+=(weight)*qRed(*(cTable+(*s))); \
3410 total_green+=(weight)*qGreen(*(cTable+(*s))); \ 3413 total_green+=(weight)*qGreen(*(cTable+(*s))); \
3411 total_blue+=(weight)*qBlue(*(cTable+(*s))); \ 3414 total_blue+=(weight)*qBlue(*(cTable+(*s))); \
3412 s++; 3415 s++;
3413 3416
3414 if(src.width() < 3 || src.height() < 3) 3417 if(src.width() < 3 || src.height() < 3)
3415 return(src); 3418 return(src);
3416 3419
3417 double total_blue, total_green, total_red; 3420 double total_blue, total_green, total_red;
3418 int x, y; 3421 int x, y;
3419 unsigned int *q; 3422 unsigned int *q;
3420 3423
3421 QImage dest(src.width(), src.height(), 32); 3424 QImage dest(src.width(), src.height(), 32);
3422 if(src.depth() > 8){ // DirectClass source image 3425 if(src.depth() > 8){ // DirectClass source image
3423 unsigned int *p, *s; 3426 unsigned int *p, *s;
3424 for(y=0; y < src.height(); ++y){ 3427 for(y=0; y < src.height(); ++y){
3425 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); 3428 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3));
3426 q = (unsigned int *)dest.scanLine(y); 3429 q = (unsigned int *)dest.scanLine(y);
3427 // emboss this row of pixels. 3430 // emboss this row of pixels.
3428 *q++=(*(p+src.width())); 3431 *q++=(*(p+src.width()));
3429 for(x=1; x < src.width()-1; ++x){ 3432 for(x=1; x < src.width()-1; ++x){
3430 // compute weighted average of target pixel color components. 3433 // compute weighted average of target pixel color components.
3431 total_red=0.0; 3434 total_red=0.0;
3432 total_green=0.0; 3435 total_green=0.0;
3433 total_blue=0.0; 3436 total_blue=0.0;
3434 s=p; 3437 s=p;
3435 Emboss(-1); Emboss(-2); Emboss( 0); 3438 Emboss(-1); Emboss(-2); Emboss( 0);
3436 s=p+src.width(); 3439 s=p+src.width();
3437 Emboss(-2); Emboss( 0); Emboss( 2); 3440 Emboss(-2); Emboss( 0); Emboss( 2);
3438 s=p+2*src.width(); 3441 s=p+2*src.width();
3439 Emboss( 0); Emboss( 2); Emboss( 1); 3442 Emboss( 0); Emboss( 2); Emboss( 1);
3440 total_red += (MaxRGB+1)/2; 3443 total_red += (MaxRGB+1)/2;
3441 total_green += (MaxRGB+1)/2; 3444 total_green += (MaxRGB+1)/2;
3442 total_blue += (MaxRGB+1)/2; 3445 total_blue += (MaxRGB+1)/2;
3443 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red), 3446 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red),
3444 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green), 3447 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green),
3445 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue), 3448 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue),
3446 255); 3449 255);
3447 p++; 3450 p++;
3448 q++; 3451 q++;
3449 } 3452 }
3450 p++; 3453 p++;
3451 *q++=(*p); 3454 *q++=(*p);
3452 } 3455 }
3453 } 3456 }
3454 else{ // PsudeoClass source image 3457 else{ // PsudeoClass source image
3455 unsigned char *p, *p2, *p3, *s; 3458 unsigned char *p, *p2, *p3, *s;
3456 unsigned int *cTable = src.colorTable(); 3459 unsigned int *cTable = src.colorTable();
3457 int scanLineIdx; 3460 int scanLineIdx;
3458 for(y=0; y < src.height(); ++y){ 3461 for(y=0; y < src.height(); ++y){
3459 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); 3462 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3);
3460 p = (unsigned char *)src.scanLine(scanLineIdx); 3463 p = (unsigned char *)src.scanLine(scanLineIdx);
3461 p2 = (unsigned char *)src.scanLine(scanLineIdx+1); 3464 p2 = (unsigned char *)src.scanLine(scanLineIdx+1);
3462 p3 = (unsigned char *)src.scanLine(scanLineIdx+2); 3465 p3 = (unsigned char *)src.scanLine(scanLineIdx+2);
3463 q = (unsigned int *)dest.scanLine(y); 3466 q = (unsigned int *)dest.scanLine(y);
3464 // emboss this row of pixels. 3467 // emboss this row of pixels.
3465 *q++=(*(cTable+(*p2))); 3468 *q++=(*(cTable+(*p2)));
3466 for(x=1; x < src.width()-1; ++x){ 3469 for(x=1; x < src.width()-1; ++x){
3467 // compute weighted average of target pixel color components. 3470 // compute weighted average of target pixel color components.
3468 total_red=0.0; 3471 total_red=0.0;
3469 total_green=0.0; 3472 total_green=0.0;
3470 total_blue=0.0; 3473 total_blue=0.0;
3471 s=p; 3474 s=p;
3472 Emboss256(-1); Emboss256(-2); Emboss256(0); 3475 Emboss256(-1); Emboss256(-2); Emboss256(0);
3473 s=p2; 3476 s=p2;
3474 Emboss256(-2); Emboss256(0); Emboss256(2); 3477 Emboss256(-2); Emboss256(0); Emboss256(2);
3475 s=p3; 3478 s=p3;
3476 Emboss256(0); Emboss256(2); Emboss256(1); 3479 Emboss256(0); Emboss256(2); Emboss256(1);
3477 total_red += (MaxRGB+1)/2; 3480 total_red += (MaxRGB+1)/2;
3478 total_green += (MaxRGB+1)/2; 3481 total_green += (MaxRGB+1)/2;
3479 total_blue += (MaxRGB+1)/2; 3482 total_blue += (MaxRGB+1)/2;
3480 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red), 3483 *q = qRgba((unsigned char)((total_red < 0) ? 0 : (total_red > MaxRGB) ? MaxRGB : total_red),
3481 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green), 3484 (unsigned char)((total_green < 0) ? 0 : (total_green > MaxRGB) ? MaxRGB : total_green),
3482 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue), 3485 (unsigned char)((total_blue < 0) ? 0 : (total_blue > MaxRGB) ? MaxRGB : total_blue),
3483 255); 3486 255);
3484 p++; 3487 p++;
3485 p2++; 3488 p2++;
3486 p3++; 3489 p3++;
3487 q++; 3490 q++;
3488 } 3491 }
3489 p++; 3492 p++;
3490 *q++=(*(cTable+(*p))); 3493 *q++=(*(cTable+(*p)));
3491 } 3494 }
3492 } 3495 }
3493 toGray(dest); 3496 toGray(dest);
3494 normalize(dest); 3497 normalize(dest);
3495 return(dest); 3498 return(dest);
3496} 3499}
3497 3500
3498QImage OImageEffect::shade(QImage &src, bool color_shading, double azimuth, 3501QImage OImageEffect::shade(QImage &src, bool color_shading, double azimuth,
3499 double elevation) 3502 double elevation)
3500{ 3503{
3501 struct PointInfo{ 3504 struct PointInfo{
3502 double x, y, z; 3505 double x, y, z;
3503 }; 3506 };
3504 3507
3505 double distance, normal_distance, shade; 3508 double distance, normal_distance, shade;
3506 int x, y; 3509 int x, y;
3507 3510
3508 struct PointInfo light, normal; 3511 struct PointInfo light, normal;
3509 3512
3510 unsigned int *q; 3513 unsigned int *q;
3511 3514
3512 QImage dest(src.width(), src.height(), 32); 3515 QImage dest(src.width(), src.height(), 32);
3513 3516
3514 azimuth = DegreesToRadians(azimuth); 3517 azimuth = DegreesToRadians(azimuth);
3515 elevation = DegreesToRadians(elevation); 3518 elevation = DegreesToRadians(elevation);
3516 light.x = MaxRGB*cos(azimuth)*cos(elevation); 3519 light.x = MaxRGB*cos(azimuth)*cos(elevation);
3517 light.y = MaxRGB*sin(azimuth)*cos(elevation); 3520 light.y = MaxRGB*sin(azimuth)*cos(elevation);
3518 light.z = MaxRGB*sin(elevation); 3521 light.z = MaxRGB*sin(elevation);
3519 normal.z= 2*MaxRGB; // constant Z of surface normal 3522 normal.z= 2*MaxRGB; // constant Z of surface normal
3520 3523
3521 if(src.depth() > 8){ // DirectClass source image 3524 if(src.depth() > 8){ // DirectClass source image
3522 unsigned int *p, *s0, *s1, *s2; 3525 unsigned int *p, *s0, *s1, *s2;
3523 for(y=0; y < src.height(); ++y){ 3526 for(y=0; y < src.height(); ++y){
3524 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); 3527 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3));
3525 q = (unsigned int *)dest.scanLine(y); 3528 q = (unsigned int *)dest.scanLine(y);
3526 // shade this row of pixels. 3529 // shade this row of pixels.
3527 *q++=(*(p+src.width())); 3530 *q++=(*(p+src.width()));
3528 p++; 3531 p++;
3529 s0 = p; 3532 s0 = p;
3530 s1 = p + src.width(); 3533 s1 = p + src.width();
3531 s2 = p + 2*src.width(); 3534 s2 = p + 2*src.width();
3532 for(x=1; x < src.width()-1; ++x){ 3535 for(x=1; x < src.width()-1; ++x){
3533 // determine the surface normal and compute shading. 3536 // determine the surface normal and compute shading.
3534 normal.x=intensityValue(*(s0-1))+intensityValue(*(s1-1))+intensityValue(*(s2-1))- 3537 normal.x=intensityValue(*(s0-1))+intensityValue(*(s1-1))+intensityValue(*(s2-1))-
3535 (double) intensityValue(*(s0+1))-(double) intensityValue(*(s1+1))- 3538 (double) intensityValue(*(s0+1))-(double) intensityValue(*(s1+1))-
3536 (double) intensityValue(*(s2+1)); 3539 (double) intensityValue(*(s2+1));
3537 normal.y=intensityValue(*(s2-1))+intensityValue(*s2)+intensityValue(*(s2+1))- 3540 normal.y=intensityValue(*(s2-1))+intensityValue(*s2)+intensityValue(*(s2+1))-
3538 (double) intensityValue(*(s0-1))-(double) intensityValue(*s0)- 3541 (double) intensityValue(*(s0-1))-(double) intensityValue(*s0)-
3539 (double) intensityValue(*(s0+1)); 3542 (double) intensityValue(*(s0+1));
3540 if((normal.x == 0) && (normal.y == 0)) 3543 if((normal.x == 0) && (normal.y == 0))
3541 shade=light.z; 3544 shade=light.z;
3542 else{ 3545 else{
3543 shade=0.0; 3546 shade=0.0;
3544 distance=normal.x*light.x+normal.y*light.y+normal.z*light.z; 3547 distance=normal.x*light.x+normal.y*light.y+normal.z*light.z;
3545 if (distance > 0.0){ 3548 if (distance > 0.0){
3546 normal_distance= 3549 normal_distance=
3547 normal.x*normal.x+normal.y*normal.y+normal.z*normal.z; 3550 normal.x*normal.x+normal.y*normal.y+normal.z*normal.z;
3548 if(fabs(normal_distance) > 0.0000001) 3551 if(fabs(normal_distance) > 0.0000001)
3549 shade=distance/sqrt(normal_distance); 3552 shade=distance/sqrt(normal_distance);
3550 } 3553 }
3551 } 3554 }
3552 if(!color_shading){ 3555 if(!color_shading){
3553 *q = qRgba((unsigned char)(shade), 3556 *q = qRgba((unsigned char)(shade),
3554 (unsigned char)(shade), 3557 (unsigned char)(shade),
3555 (unsigned char)(shade), 3558 (unsigned char)(shade),
3556 qAlpha(*s1)); 3559 qAlpha(*s1));
3557 } 3560 }
3558 else{ 3561 else{
3559 *q = qRgba((unsigned char)((shade*qRed(*s1))/(MaxRGB+1)), 3562 *q = qRgba((unsigned char)((shade*qRed(*s1))/(MaxRGB+1)),
3560 (unsigned char)((shade*qGreen(*s1))/(MaxRGB+1)), 3563 (unsigned char)((shade*qGreen(*s1))/(MaxRGB+1)),
3561 (unsigned char)((shade*qBlue(*s1))/(MaxRGB+1)), 3564 (unsigned char)((shade*qBlue(*s1))/(MaxRGB+1)),
3562 qAlpha(*s1)); 3565 qAlpha(*s1));
3563 } 3566 }
3564 ++s0; 3567 ++s0;
3565 ++s1; 3568 ++s1;
3566 ++s2; 3569 ++s2;
3567 q++; 3570 q++;
3568 } 3571 }
3569 *q++=(*s1); 3572 *q++=(*s1);
3570 } 3573 }
3571 } 3574 }
3572 else{ // PsudeoClass source image 3575 else{ // PsudeoClass source image
3573 unsigned char *p, *s0, *s1, *s2; 3576 unsigned char *p, *s0, *s1, *s2;
3574 int scanLineIdx; 3577 int scanLineIdx;
3575 unsigned int *cTable = (unsigned int *)src.colorTable(); 3578 unsigned int *cTable = (unsigned int *)src.colorTable();
3576 for(y=0; y < src.height(); ++y){ 3579 for(y=0; y < src.height(); ++y){
3577 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); 3580 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3);
3578 p = (unsigned char *)src.scanLine(scanLineIdx); 3581 p = (unsigned char *)src.scanLine(scanLineIdx);
3579 q = (unsigned int *)dest.scanLine(y); 3582 q = (unsigned int *)dest.scanLine(y);
3580 // shade this row of pixels. 3583 // shade this row of pixels.
3581 s0 = p; 3584 s0 = p;
3582 s1 = (unsigned char *) src.scanLine(scanLineIdx+1); 3585 s1 = (unsigned char *) src.scanLine(scanLineIdx+1);
3583 s2 = (unsigned char *) src.scanLine(scanLineIdx+2); 3586 s2 = (unsigned char *) src.scanLine(scanLineIdx+2);
3584 *q++=(*(cTable+(*s1))); 3587 *q++=(*(cTable+(*s1)));
3585 ++p; 3588 ++p;
3586 ++s0; 3589 ++s0;
3587 ++s1; 3590 ++s1;
3588 ++s2; 3591 ++s2;
3589 for(x=1; x < src.width()-1; ++x){ 3592 for(x=1; x < src.width()-1; ++x){
3590 // determine the surface normal and compute shading. 3593 // determine the surface normal and compute shading.
3591 normal.x=intensityValue(*(cTable+(*(s0-1))))+intensityValue(*(cTable+(*(s1-1))))+intensityValue(*(cTable+(*(s2-1))))- 3594 normal.x=intensityValue(*(cTable+(*(s0-1))))+intensityValue(*(cTable+(*(s1-1))))+intensityValue(*(cTable+(*(s2-1))))-
3592 (double) intensityValue(*(cTable+(*(s0+1))))-(double) intensityValue(*(cTable+(*(s1+1))))- 3595 (double) intensityValue(*(cTable+(*(s0+1))))-(double) intensityValue(*(cTable+(*(s1+1))))-
3593 (double) intensityValue(*(cTable+(*(s2+1)))); 3596 (double) intensityValue(*(cTable+(*(s2+1))));
3594 normal.y=intensityValue(*(cTable+(*(s2-1))))+intensityValue(*(cTable+(*s2)))+intensityValue(*(cTable+(*(s2+1))))- 3597 normal.y=intensityValue(*(cTable+(*(s2-1))))+intensityValue(*(cTable+(*s2)))+intensityValue(*(cTable+(*(s2+1))))-
3595 (double) intensityValue(*(cTable+(*(s0-1))))-(double) intensityValue(*(cTable+(*s0)))- 3598 (double) intensityValue(*(cTable+(*(s0-1))))-(double) intensityValue(*(cTable+(*s0)))-
3596 (double) intensityValue(*(cTable+(*(s0+1)))); 3599 (double) intensityValue(*(cTable+(*(s0+1))));
3597 if((normal.x == 0) && (normal.y == 0)) 3600 if((normal.x == 0) && (normal.y == 0))
3598 shade=light.z; 3601 shade=light.z;
3599 else{ 3602 else{
3600 shade=0.0; 3603 shade=0.0;
3601 distance=normal.x*light.x+normal.y*light.y+normal.z*light.z; 3604 distance=normal.x*light.x+normal.y*light.y+normal.z*light.z;
3602 if (distance > 0.0){ 3605 if (distance > 0.0){
3603 normal_distance= 3606 normal_distance=
3604 normal.x*normal.x+normal.y*normal.y+normal.z*normal.z; 3607 normal.x*normal.x+normal.y*normal.y+normal.z*normal.z;
3605 if(fabs(normal_distance) > 0.0000001) 3608 if(fabs(normal_distance) > 0.0000001)
3606 shade=distance/sqrt(normal_distance); 3609 shade=distance/sqrt(normal_distance);
3607 } 3610 }
3608 } 3611 }
3609 if(!color_shading){ 3612 if(!color_shading){
3610 *q = qRgba((unsigned char)(shade), 3613 *q = qRgba((unsigned char)(shade),
3611 (unsigned char)(shade), 3614 (unsigned char)(shade),
3612 (unsigned char)(shade), 3615 (unsigned char)(shade),
3613 qAlpha(*(cTable+(*s1)))); 3616 qAlpha(*(cTable+(*s1))));
3614 } 3617 }
3615 else{ 3618 else{
3616 *q = qRgba((unsigned char)((shade*qRed(*(cTable+(*s1))))/(MaxRGB+1)), 3619 *q = qRgba((unsigned char)((shade*qRed(*(cTable+(*s1))))/(MaxRGB+1)),
3617 (unsigned char)((shade*qGreen(*(cTable+(*s1))))/(MaxRGB+1)), 3620 (unsigned char)((shade*qGreen(*(cTable+(*s1))))/(MaxRGB+1)),
3618 (unsigned char)((shade*qBlue(*(cTable+(*s1))))/(MaxRGB+1)), 3621 (unsigned char)((shade*qBlue(*(cTable+(*s1))))/(MaxRGB+1)),
3619 qAlpha(*s1)); 3622 qAlpha(*s1));
3620 } 3623 }
3621 ++s0; 3624 ++s0;
3622 ++s1; 3625 ++s1;
3623 ++s2; 3626 ++s2;
3624 q++; 3627 q++;
3625 } 3628 }
3626 *q++=(*(cTable+(*s1))); 3629 *q++=(*(cTable+(*s1)));
3627 } 3630 }
3628 } 3631 }
3629 return(dest); 3632 return(dest);
3630} 3633}
3631 3634
3632QImage OImageEffect::blur(QImage &src, double factor) 3635QImage OImageEffect::blur(QImage &src, double factor)
3633{ 3636{
3634 3637
3635#define Blur(weight) \ 3638#define Blur(weight) \
3636 total_red+=(weight)*qRed(*s); \ 3639 total_red+=(weight)*qRed(*s); \
3637 total_green+=(weight)*qGreen(*s); \ 3640 total_green+=(weight)*qGreen(*s); \
3638 total_blue+=(weight)*qBlue(*s); \ 3641 total_blue+=(weight)*qBlue(*s); \
3639 total_opacity+=(weight)*qAlpha(*s); \ 3642 total_opacity+=(weight)*qAlpha(*s); \
3640 s++; 3643 s++;
3641 3644
3642#define Blur256(weight) \ 3645#define Blur256(weight) \
3643 total_red+=(weight)*qRed(*(cTable+(*s))); \ 3646 total_red+=(weight)*qRed(*(cTable+(*s))); \
3644 total_green+=(weight)*qGreen(*(cTable+(*s))); \ 3647 total_green+=(weight)*qGreen(*(cTable+(*s))); \
3645 total_blue+=(weight)*qBlue(*(cTable+(*s))); \ 3648 total_blue+=(weight)*qBlue(*(cTable+(*s))); \
3646 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \ 3649 total_opacity+=(weight)*qAlpha(*(cTable+(*s))); \
3647 s++; 3650 s++;
3648 3651
3649 if(src.width() < 3 || src.height() < 3) 3652 if(src.width() < 3 || src.height() < 3)
3650 return(src); 3653 return(src);
3651 3654
3652 double quantum, total_blue, total_green, total_opacity, total_red, weight; 3655 double quantum, total_blue, total_green, total_opacity, total_red, weight;
3653 3656
3654 int x, y; 3657 int x, y;
3655 unsigned int *q; 3658 unsigned int *q;
3656 3659
3657 QImage dest(src.width(), src.height(), 32); 3660 QImage dest(src.width(), src.height(), 32);
3658 weight=((100.0-factor)/2)+1; 3661 weight=((100.0-factor)/2)+1;
3659 quantum = QMAX(weight+12.0, 1.0); 3662 quantum = QMAX(weight+12.0, 1.0);
3660 if(src.depth() > 8){ // DirectClass source image 3663 if(src.depth() > 8){ // DirectClass source image
3661 unsigned int *p, *s; 3664 unsigned int *p, *s;
3662 for(y=0; y < src.height(); ++y){ 3665 for(y=0; y < src.height(); ++y){
3663 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); 3666 p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3));
3664 q = (unsigned int *)dest.scanLine(y); 3667 q = (unsigned int *)dest.scanLine(y);
3665 // blur this row of pixels. 3668 // blur this row of pixels.
3666 *q++=(*(p+src.width())); 3669 *q++=(*(p+src.width()));
3667 for(x=1; x < src.width()-1; ++x){ 3670 for(x=1; x < src.width()-1; ++x){
3668 // compute weighted average of target pixel color components. 3671 // compute weighted average of target pixel color components.
3669 total_red=0.0; 3672 total_red=0.0;
3670 total_green=0.0; 3673 total_green=0.0;
3671 total_blue=0.0; 3674 total_blue=0.0;
3672 total_opacity=0.0; 3675 total_opacity=0.0;
3673 s=p; 3676 s=p;
3674 Blur(1); Blur(2); Blur(1); 3677 Blur(1); Blur(2); Blur(1);
3675 s=p+src.width(); 3678 s=p+src.width();
3676 Blur(2); Blur(weight); Blur(2); 3679 Blur(2); Blur(weight); Blur(2);
3677 s=p+2*src.width(); 3680 s=p+2*src.width();
3678 Blur(1); Blur(2); Blur(1); 3681 Blur(1); Blur(2); Blur(1);
3679 *q = qRgba((unsigned char)((total_red+(quantum/2))/quantum), 3682 *q = qRgba((unsigned char)((total_red+(quantum/2))/quantum),
3680 (unsigned char)((total_green+(quantum/2))/quantum), 3683 (unsigned char)((total_green+(quantum/2))/quantum),
3681 (unsigned char)((total_blue+(quantum/2))/quantum), 3684 (unsigned char)((total_blue+(quantum/2))/quantum),
3682 (unsigned char)((total_opacity+(quantum/2))/quantum)); 3685 (unsigned char)((total_opacity+(quantum/2))/quantum));
3683 p++; 3686 p++;
3684 q++; 3687 q++;
3685 } 3688 }
3686 p++; 3689 p++;
3687 *q++=(*p); 3690 *q++=(*p);
3688 } 3691 }
3689 } 3692 }
3690 else{ // PsudeoClass source image 3693 else{ // PsudeoClass source image
3691 unsigned char *p, *p2, *p3, *s; 3694 unsigned char *p, *p2, *p3, *s;
3692 unsigned int *cTable = src.colorTable(); 3695 unsigned int *cTable = src.colorTable();
3693 int scanLineIdx; 3696 int scanLineIdx;
3694 for(y=0; y < src.height(); ++y){ 3697 for(y=0; y < src.height(); ++y){
3695 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); 3698 scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3);
3696 p = (unsigned char *)src.scanLine(scanLineIdx); 3699 p = (unsigned char *)src.scanLine(scanLineIdx);
3697 p2 = (unsigned char *)src.scanLine(scanLineIdx+1); 3700 p2 = (unsigned char *)src.scanLine(scanLineIdx+1);
3698 p3 = (unsigned char *)src.scanLine(scanLineIdx+2); 3701 p3 = (unsigned char *)src.scanLine(scanLineIdx+2);
3699 q = (unsigned int *)dest.scanLine(y); 3702 q = (unsigned int *)dest.scanLine(y);
3700 // blur this row of pixels. 3703 // blur this row of pixels.
3701 *q++=(*(cTable+(*p2))); 3704 *q++=(*(cTable+(*p2)));
3702 for(x=1; x < src.width()-1; ++x){ 3705 for(x=1; x < src.width()-1; ++x){
3703 // compute weighted average of target pixel color components. 3706 // compute weighted average of target pixel color components.
3704 total_red=0.0; 3707 total_red=0.0;
3705 total_green=0.0; 3708 total_green=0.0;
3706 total_blue=0.0; 3709 total_blue=0.0;
3707 total_opacity=0.0; 3710 total_opacity=0.0;
3708 s=p; 3711 s=p;
3709 Blur256(1); Blur256(2); Blur256(1); 3712 Blur256(1); Blur256(2); Blur256(1);
3710 s=p2; 3713 s=p2;
3711 Blur256(2); Blur256(weight); Blur256(2); 3714 Blur256(2); Blur256(weight); Blur256(2);
3712 s=p3; 3715 s=p3;
3713 Blur256(1); Blur256(2); Blur256(1); 3716 Blur256(1); Blur256(2); Blur256(1);
3714 *q = qRgba((unsigned char)((total_red+(quantum/2))/quantum), 3717 *q = qRgba((unsigned char)((total_red+(quantum/2))/quantum),
3715 (unsigned char)((total_green+(quantum/2))/quantum), 3718 (unsigned char)((total_green+(quantum/2))/quantum),
3716 (unsigned char)((total_blue+(quantum/2))/quantum), 3719 (unsigned char)((total_blue+(quantum/2))/quantum),
3717 (unsigned char)((total_opacity+(quantum/2))/quantum)); 3720 (unsigned char)((total_opacity+(quantum/2))/quantum));
3718 p++; 3721 p++;
3719 p2++; 3722 p2++;
3720 p3++; 3723 p3++;
3721 q++; 3724 q++;
3722 } 3725 }
3723 p++; 3726 p++;
3724 *q++=(*(cTable+(*p))); 3727 *q++=(*(cTable+(*p)));
3725 } 3728 }
3726 } 3729 }
3727 return(dest); 3730 return(dest);
3728} 3731}
3729 3732
3730// High quality, expensive HSV contrast. You can do a faster one by just 3733// High quality, expensive HSV contrast. You can do a faster one by just
3731// taking a grayscale threshold (ie: 128) and incrementing RGB color 3734// taking a grayscale threshold (ie: 128) and incrementing RGB color
3732// channels above it and decrementing those below it, but this gives much 3735// channels above it and decrementing those below it, but this gives much
3733// better results. (mosfet 12/28/01) 3736// better results. (mosfet 12/28/01)
3734void OImageEffect::contrastHSV(QImage &img, bool sharpen) 3737void OImageEffect::contrastHSV(QImage &img, bool sharpen)
3735{ 3738{
3736 int i, sign; 3739 int i, sign;
3737 unsigned int *data; 3740 unsigned int *data;
3738 int count; 3741 int count;
3739 double brightness, scale, theta; 3742 double brightness, scale, theta;
3740 QColor c; 3743 QColor c;
3741 int h, s, v; 3744 int h, s, v;
3742 3745
3743 sign = sharpen ? 1 : -1; 3746 sign = sharpen ? 1 : -1;
3744 scale=0.5000000000000001; 3747 scale=0.5000000000000001;
3745 if(img.depth() > 8){ 3748 if(img.depth() > 8){
3746 count = img.width()*img.height(); 3749 count = img.width()*img.height();
3747 data = (unsigned int *)img.bits(); 3750 data = (unsigned int *)img.bits();
3748 } 3751 }
3749 else{ 3752 else{
3750 count = img.numColors(); 3753 count = img.numColors();
3751 data = (unsigned int *)img.colorTable(); 3754 data = (unsigned int *)img.colorTable();
3752 } 3755 }
3753 for(i=0; i < count; ++i){ 3756 for(i=0; i < count; ++i){
3754 c.setRgb(data[i]); 3757 c.setRgb(data[i]);
3755 c.hsv(&h, &s, &v); 3758 c.hsv(&h, &s, &v);
3756 brightness = v/255.0; 3759 brightness = v/255.0;
3757 theta=(brightness-0.5)*M_PI; 3760 theta=(brightness-0.5)*M_PI;
3758 brightness+=scale*(((scale*((sin(theta)+1.0)))-brightness)*sign); 3761 brightness+=scale*(((scale*((sin(theta)+1.0)))-brightness)*sign);
3759 if (brightness > 1.0) 3762 if (brightness > 1.0)
3760 brightness=1.0; 3763 brightness=1.0;
3761 else 3764 else
3762 if (brightness < 0) 3765 if (brightness < 0)
3763 brightness=0.0; 3766 brightness=0.0;
3764 v = (int)(brightness*255); 3767 v = (int)(brightness*255);
3765 c.setHsv(h, s, v); 3768 c.setHsv(h, s, v);
3766 data[i] = qRgba(c.red(), c.green(), c.blue(), qAlpha(data[i])); 3769 data[i] = qRgba(c.red(), c.green(), c.blue(), qAlpha(data[i]));
3767 } 3770 }
3768} 3771}
3769 3772
3770 3773
3771 3774
3772} 3775}
3773} 3776}
diff --git a/library/global.cpp b/library/global.cpp
index 7bdd0b1..1895006 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -1,860 +1,864 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#define QTOPIA_INTERNAL_LANGLIST 20#define QTOPIA_INTERNAL_LANGLIST
21#include <qpe/qpedebug.h> 21#include <qpe/qpedebug.h>
22#include <qpe/global.h> 22#include <qpe/global.h>
23#include <qpe/qdawg.h> 23#include <qpe/qdawg.h>
24#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
25#include <qpe/resource.h> 25#include <qpe/resource.h>
26#include <qpe/storage.h> 26#include <qpe/storage.h>
27#include <qpe/applnk.h> 27#include <qpe/applnk.h>
28#include <qpe/qcopenvelope_qws.h> 28#include <qpe/qcopenvelope_qws.h>
29#include <qpe/config.h> 29#include <qpe/config.h>
30 30
31#include <qlabel.h> 31#include <qlabel.h>
32#include <qtimer.h> 32#include <qtimer.h>
33#include <qmap.h> 33#include <qmap.h>
34#include <qdict.h> 34#include <qdict.h>
35#include <qdir.h> 35#include <qdir.h>
36#include <qmessagebox.h> 36#include <qmessagebox.h>
37#include <qregexp.h> 37#include <qregexp.h>
38 38
39#include <stdlib.h> 39#include <stdlib.h>
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/wait.h> 41#include <sys/wait.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <errno.h> 45#include <errno.h>
46 46
47#include <qwindowsystem_qws.h> // for qwsServer 47#include <qwindowsystem_qws.h> // for qwsServer
48#include <qdatetime.h> 48#include <qdatetime.h>
49 49
50 50
51//#include "quickexec_p.h" 51//#include "quickexec_p.h"
52 52
53class Emitter : public QObject { 53class Emitter : public QObject {
54 Q_OBJECT 54 Q_OBJECT
55public: 55public:
56 Emitter( QWidget* receiver, const QString& document ) 56 Emitter( QWidget* receiver, const QString& document )
57 { 57 {
58 connect(this, SIGNAL(setDocument(const QString&)), 58 connect(this, SIGNAL(setDocument(const QString&)),
59 receiver, SLOT(setDocument(const QString&))); 59 receiver, SLOT(setDocument(const QString&)));
60 emit setDocument(document); 60 emit setDocument(document);
61 disconnect(this, SIGNAL(setDocument(const QString&)), 61 disconnect(this, SIGNAL(setDocument(const QString&)),
62 receiver, SLOT(setDocument(const QString&))); 62 receiver, SLOT(setDocument(const QString&)));
63 } 63 }
64 64
65signals: 65signals:
66 void setDocument(const QString&); 66 void setDocument(const QString&);
67}; 67};
68 68
69 69
70class StartingAppList : public QObject { 70class StartingAppList : public QObject {
71 Q_OBJECT 71 Q_OBJECT
72public: 72public:
73 static void add( const QString& name ); 73 static void add( const QString& name );
74 static bool isStarting( const QString name ); 74 static bool isStarting( const QString name );
75private slots: 75private slots:
76 void handleNewChannel( const QString &); 76 void handleNewChannel( const QString &);
77private: 77private:
78 StartingAppList( QObject *parent=0, const char* name=0 ) ; 78 StartingAppList( QObject *parent=0, const char* name=0 ) ;
79 79
80 QDict<QTime> dict; 80 QDict<QTime> dict;
81 static StartingAppList *appl; 81 static StartingAppList *appl;
82}; 82};
83 83
84StartingAppList* StartingAppList::appl = 0; 84StartingAppList* StartingAppList::appl = 0;
85 85
86StartingAppList::StartingAppList( QObject *parent, const char* name ) 86StartingAppList::StartingAppList( QObject *parent, const char* name )
87 :QObject( parent, name ) 87 :QObject( parent, name )
88{ 88{
89#if QT_VERSION >= 232 && defined(QWS) 89#if QT_VERSION >= 232 && defined(QWS)
90 connect( qwsServer, SIGNAL( newChannel(const QString&)), 90 connect( qwsServer, SIGNAL( newChannel(const QString&)),
91 this, SLOT( handleNewChannel(const QString&)) ); 91 this, SLOT( handleNewChannel(const QString&)) );
92#endif 92#endif
93 dict.setAutoDelete( TRUE ); 93 dict.setAutoDelete( TRUE );
94} 94}
95 95
96void StartingAppList::add( const QString& name ) 96void StartingAppList::add( const QString& name )
97{ 97{
98#if QT_VERSION >= 232 && !defined(QT_NO_COP) 98#if QT_VERSION >= 232 && !defined(QT_NO_COP)
99 if ( !appl ) 99 if ( !appl )
100 appl = new StartingAppList; 100 appl = new StartingAppList;
101 QTime *t = new QTime; 101 QTime *t = new QTime;
102 t->start(); 102 t->start();
103 appl->dict.insert( "QPE/Application/" + name, t ); 103 appl->dict.insert( "QPE/Application/" + name, t );
104#endif 104#endif
105} 105}
106 106
107bool StartingAppList::isStarting( const QString name ) 107bool StartingAppList::isStarting( const QString name )
108{ 108{
109#if QT_VERSION >= 232 && !defined(QT_NO_COP) 109#if QT_VERSION >= 232 && !defined(QT_NO_COP)
110 if ( appl ) { 110 if ( appl ) {
111 QTime *t = appl->dict.find( "QPE/Application/" + name ); 111 QTime *t = appl->dict.find( "QPE/Application/" + name );
112 if ( !t ) 112 if ( !t )
113 return FALSE; 113 return FALSE;
114 if ( t->elapsed() > 10000 ) { 114 if ( t->elapsed() > 10000 ) {
115 // timeout in case of crash or something 115 // timeout in case of crash or something
116 appl->dict.remove( "QPE/Application/" + name ); 116 appl->dict.remove( "QPE/Application/" + name );
117 return FALSE; 117 return FALSE;
118 } 118 }
119 return TRUE; 119 return TRUE;
120 } 120 }
121#endif 121#endif
122 return FALSE; 122 return FALSE;
123} 123}
124 124
125void StartingAppList::handleNewChannel( const QString & name ) 125void StartingAppList::handleNewChannel( const QString & name )
126{ 126{
127#if QT_VERSION >= 232 && !defined(QT_NO_COP) 127#if QT_VERSION >= 232 && !defined(QT_NO_COP)
128 dict.remove( name ); 128 dict.remove( name );
129#endif 129#endif
130} 130}
131 131
132static bool docDirCreated = FALSE; 132static bool docDirCreated = FALSE;
133static QDawg* fixed_dawg = 0; 133static QDawg* fixed_dawg = 0;
134static QDict<QDawg> *named_dawg = 0; 134static QDict<QDawg> *named_dawg = 0;
135 135
136static QString qpeDir() 136static QString qpeDir()
137{ 137{
138 QString dir = getenv("OPIEDIR"); 138 QString dir = getenv("OPIEDIR");
139 if ( dir.isEmpty() ) dir = ".."; 139 if ( dir.isEmpty() ) dir = "..";
140 return dir; 140 return dir;
141} 141}
142 142
143static QString dictDir() 143static QString dictDir()
144{ 144{
145 return qpeDir() + "/etc/dict"; 145 return qpeDir() + "/etc/dict";
146} 146}
147 147
148/*! 148/*!
149 \class Global global.h 149 \class Global global.h
150 \brief The Global class provides application-wide global functions. 150 \brief The Global class provides application-wide global functions.
151 151
152 The Global functions are grouped as follows: 152 The Global functions are grouped as follows:
153 \tableofcontents 153 \tableofcontents
154 154
155 \section1 User Interface 155 \section1 User Interface
156 156
157 The statusMessage() function provides short-duration messages to the 157 The statusMessage() function provides short-duration messages to the
158 user. The showInputMethod() function shows the current input method, 158 user. The showInputMethod() function shows the current input method,
159 and hideInputMethod() hides the input method. 159 and hideInputMethod() hides the input method.
160 160
161 \section1 Document related 161 \section1 Document related
162 162
163 The findDocuments() function creates a set of \link doclnk.html 163 The findDocuments() function creates a set of \link doclnk.html
164 DocLnk\endlink objects in a particular folder. 164 DocLnk\endlink objects in a particular folder.
165 165
166 \section1 Filesystem related 166 \section1 Filesystem related
167 167
168 Global provides an applicationFileName() function that returns the 168 Global provides an applicationFileName() function that returns the
169 full path of an application-specific file. 169 full path of an application-specific file.
170 170
171 The execute() function runs an application. 171 The execute() function runs an application.
172 172
173 \section1 Word list related 173 \section1 Word list related
174 174
175 A list of words relevant to the current locale is maintained by the 175 A list of words relevant to the current locale is maintained by the
176 system. The list is held in a \link qdawg.html DAWG\endlink 176 system. The list is held in a \link qdawg.html DAWG\endlink
177 (implemented by the QDawg class). This list is used, for example, by 177 (implemented by the QDawg class). This list is used, for example, by
178 the pickboard input method. 178 the pickboard input method.
179 179
180 The global QDawg is returned by fixedDawg(); this cannot be updated. 180 The global QDawg is returned by fixedDawg(); this cannot be updated.
181 An updatable copy of the global QDawg is returned by addedDawg(). 181 An updatable copy of the global QDawg is returned by addedDawg().
182 Applications may have their own word lists stored in \l{QDawg}s 182 Applications may have their own word lists stored in \l{QDawg}s
183 which are returned by dawg(). Use addWords() to add words to the 183 which are returned by dawg(). Use addWords() to add words to the
184 updateable copy of the global QDawg or to named application 184 updateable copy of the global QDawg or to named application
185 \l{QDawg}s. 185 \l{QDawg}s.
186 186
187 \section1 Quoting 187 \section1 Quoting
188 188
189 The shellQuote() function quotes a string suitable for passing to a 189 The shellQuote() function quotes a string suitable for passing to a
190 shell. The stringQuote() function backslash escapes '\' and '"' 190 shell. The stringQuote() function backslash escapes '\' and '"'
191 characters. 191 characters.
192 192
193 \section1 Hardware 193 \section1 Hardware
194 194
195 The implementation of the writeHWClock() function depends on the AlarmServer 195 The implementation of the writeHWClock() function depends on the AlarmServer
196 implementation. If the AlarmServer is using atd the clock will be synced to 196 implementation. If the AlarmServer is using atd the clock will be synced to
197 hardware. If opie-alarm is used the hardware clock will be synced before 197 hardware. If opie-alarm is used the hardware clock will be synced before
198 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation 198 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation
199 199
200 \ingroup qtopiaemb 200 \ingroup qtopiaemb
201*/ 201*/
202 202
203/*! 203/*!
204 \internal 204 \internal
205*/ 205*/
206Global::Global() 206Global::Global()
207{ 207{
208} 208}
209 209
210/*! 210/*!
211 Returns the unchangeable QDawg that contains general 211 Returns the unchangeable QDawg that contains general
212 words for the current locale. 212 words for the current locale.
213 213
214 \sa addedDawg() 214 \sa addedDawg()
215*/ 215*/
216const QDawg& Global::fixedDawg() 216const QDawg& Global::fixedDawg()
217{ 217{
218 if ( !fixed_dawg ) { 218 if ( !fixed_dawg ) {
219 if ( !docDirCreated ) 219 if ( !docDirCreated )
220 createDocDir(); 220 createDocDir();
221 221
222 fixed_dawg = new QDawg; 222 fixed_dawg = new QDawg;
223 QString dawgfilename = dictDir() + "/dawg"; 223 QString dawgfilename = dictDir() + "/dawg";
224 QString words_lang; 224 QString words_lang;
225 QStringList langs = Global::languageList(); 225 QStringList langs = Global::languageList();
226 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { 226 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
227 QString lang = *it; 227 QString lang = *it;
228 words_lang = dictDir() + "/words." + lang; 228 words_lang = dictDir() + "/words." + lang;
229 QString dawgfilename_lang = dawgfilename + "." + lang; 229 QString dawgfilename_lang = dawgfilename + "." + lang;
230 if ( QFile::exists(dawgfilename_lang) || 230 if ( QFile::exists(dawgfilename_lang) ||
231 QFile::exists(words_lang) ) { 231 QFile::exists(words_lang) ) {
232 dawgfilename = dawgfilename_lang; 232 dawgfilename = dawgfilename_lang;
233 break; 233 break;
234 } 234 }
235 } 235 }
236 QFile dawgfile(dawgfilename); 236 QFile dawgfile(dawgfilename);
237 237
238 if ( !dawgfile.exists() ) { 238 if ( !dawgfile.exists() ) {
239 QString fn = dictDir() + "/words"; 239 QString fn = dictDir() + "/words";
240 if ( QFile::exists(words_lang) ) 240 if ( QFile::exists(words_lang) )
241 fn = words_lang; 241 fn = words_lang;
242 QFile in(fn); 242 QFile in(fn);
243 if ( in.open(IO_ReadOnly) ) { 243 if ( in.open(IO_ReadOnly) ) {
244 fixed_dawg->createFromWords(&in); 244 fixed_dawg->createFromWords(&in);
245 if (dawgfile.open(IO_WriteOnly)) 245 if (dawgfile.open(IO_WriteOnly))
246 fixed_dawg->write(&dawgfile); 246 fixed_dawg->write(&dawgfile);
247 dawgfile.close(); 247 dawgfile.close();
248 } 248 }
249 } else 249 } else
250 fixed_dawg->readFile(dawgfilename); 250 fixed_dawg->readFile(dawgfilename);
251 } 251 }
252 252
253 return *fixed_dawg; 253 return *fixed_dawg;
254} 254}
255 255
256/*! 256/*!
257 Returns the changeable QDawg that contains general 257 Returns the changeable QDawg that contains general
258 words for the current locale. 258 words for the current locale.
259 259
260 \sa fixedDawg() 260 \sa fixedDawg()
261*/ 261*/
262const QDawg& Global::addedDawg() 262const QDawg& Global::addedDawg()
263{ 263{
264 return dawg("local"); 264 return dawg("local");
265} 265}
266 266
267/*! 267/*!
268 Returns the QDawg with the given \a name. 268 Returns the QDawg with the given \a name.
269 This is an application-specific word list. 269 This is an application-specific word list.
270 270
271 \a name should not contain "/". 271 \a name should not contain "/".
272*/ 272*/
273const QDawg& Global::dawg(const QString& name) 273const QDawg& Global::dawg(const QString& name)
274{ 274{
275 createDocDir(); 275 createDocDir();
276 if ( !named_dawg ) 276 if ( !named_dawg )
277 named_dawg = new QDict<QDawg>; 277 named_dawg = new QDict<QDawg>;
278 QDawg* r = named_dawg->find(name); 278 QDawg* r = named_dawg->find(name);
279 if ( !r ) { 279 if ( !r ) {
280 r = new QDawg; 280 r = new QDawg;
281 named_dawg->insert(name,r); 281 named_dawg->insert(name,r);
282 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; 282 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg";
283 QFile dawgfile(dawgfilename); 283 QFile dawgfile(dawgfilename);
284 if ( dawgfile.open(IO_ReadOnly) ) 284 if ( dawgfile.open(IO_ReadOnly) )
285 r->readFile(dawgfilename); 285 r->readFile(dawgfilename);
286 } 286 }
287 return *r; 287 return *r;
288} 288}
289 289
290/*! 290/*!
291 \overload 291 \overload
292 Adds \a wordlist to the addedDawg(). 292 Adds \a wordlist to the addedDawg().
293 293
294 Note that the addition of words persists between program executions 294 Note that the addition of words persists between program executions
295 (they are saved in the dictionary files), so you should confirm the 295 (they are saved in the dictionary files), so you should confirm the
296 words with the user before adding them. 296 words with the user before adding them.
297*/ 297*/
298void Global::addWords(const QStringList& wordlist) 298void Global::addWords(const QStringList& wordlist)
299{ 299{
300 addWords("local",wordlist); 300 addWords("local",wordlist);
301} 301}
302 302
303/*! 303/*!
304 \overload 304 \overload
305 Adds \a wordlist to the addedDawg(). 305 Adds \a wordlist to the addedDawg().
306 306
307 Note that the addition of words persists between program executions 307 Note that the addition of words persists between program executions
308 (they are saved in the dictionary files), so you should confirm the 308 (they are saved in the dictionary files), so you should confirm the
309 words with the user before adding them. 309 words with the user before adding them.
310*/ 310*/
311void Global::addWords(const QString& dictname, const QStringList& wordlist) 311void Global::addWords(const QString& dictname, const QStringList& wordlist)
312{ 312{
313 QDawg& d = (QDawg&)dawg(dictname); 313 QDawg& d = (QDawg&)dawg(dictname);
314 QStringList all = d.allWords() + wordlist; 314 QStringList all = d.allWords() + wordlist;
315 d.createFromWords(all); 315 d.createFromWords(all);
316 316
317 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; 317 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg";
318 QFile dawgfile(dawgfilename); 318 QFile dawgfile(dawgfilename);
319 if ( dawgfile.open(IO_WriteOnly) ) { 319 if ( dawgfile.open(IO_WriteOnly) ) {
320 d.write(&dawgfile); 320 d.write(&dawgfile);
321 dawgfile.close(); 321 dawgfile.close();
322 } 322 }
323 323
324 // #### Re-read the dawg here if we use mmap(). 324 // #### Re-read the dawg here if we use mmap().
325 325
326 // #### Signal other processes to re-read. 326 // #### Signal other processes to re-read.
327} 327}
328 328
329 329
330/*! 330/*!
331 Returns the full path for the application called \a appname, with the 331 Returns the full path for the application called \a appname, with the
332 given \a filename. Returns QString::null if there was a problem creating 332 given \a filename. Returns QString::null if there was a problem creating
333 the directory tree for \a appname. 333 the directory tree for \a appname.
334 If \a filename contains "/", it is the caller's responsibility to 334 If \a filename contains "/", it is the caller's responsibility to
335 ensure that those directories exist. 335 ensure that those directories exist.
336*/ 336*/
337QString Global::applicationFileName(const QString& appname, const QString& filename) 337QString Global::applicationFileName(const QString& appname, const QString& filename)
338{ 338{
339 QDir d; 339 QDir d;
340 QString r = getenv("HOME"); 340 QString r = getenv("HOME");
341 r += "/Applications/"; 341 r += "/Applications/";
342 if ( !QFile::exists( r ) ) 342 if ( !QFile::exists( r ) )
343 if ( d.mkdir(r) == false ) 343 if ( d.mkdir(r) == false )
344 return QString::null; 344 return QString::null;
345 r += appname; 345 r += appname;
346 if ( !QFile::exists( r ) ) 346 if ( !QFile::exists( r ) )
347 if ( d.mkdir(r) == false ) 347 if ( d.mkdir(r) == false )
348 return QString::null; 348 return QString::null;
349 r += "/"; r += filename; 349 r += "/"; r += filename;
350 return r; 350 return r;
351} 351}
352 352
353/*! 353/*!
354 \internal 354 \internal
355*/ 355*/
356void Global::createDocDir() 356void Global::createDocDir()
357{ 357{
358 if ( !docDirCreated ) { 358 if ( !docDirCreated ) {
359 docDirCreated = TRUE; 359 docDirCreated = TRUE;
360 mkdir( QPEApplication::documentDir().latin1(), 0755 ); 360 mkdir( QPEApplication::documentDir().latin1(), 0755 );
361 } 361 }
362} 362}
363 363
364 364
365/*! 365/*!
366 Displays a status \a message to the user. This usually appears 366 Displays a status \a message to the user. This usually appears
367 in the taskbar for a short amount of time, then disappears. 367 in the taskbar for a short amount of time, then disappears.
368*/ 368*/
369void Global::statusMessage(const QString& message) 369void Global::statusMessage(const QString& message)
370{ 370{
371#if !defined(QT_NO_COP) 371#if !defined(QT_NO_COP)
372 QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); 372 QCopEnvelope e( "QPE/TaskBar", "message(QString)" );
373 e << message; 373 e << message;
374#endif 374#endif
375} 375}
376 376
377/*! 377/*!
378 \internal 378 \internal
379*/ 379*/
380void Global::applyStyle() 380void Global::applyStyle()
381{ 381{
382#if !defined(QT_NO_COP) 382#if !defined(QT_NO_COP)
383 QCopChannel::send( "QPE/System", "applyStyle()" ); 383 QCopChannel::send( "QPE/System", "applyStyle()" );
384#else 384#else
385 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version 385 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version
386#endif 386#endif
387} 387}
388 388
389/*! 389/*!
390 \internal 390 \internal
391*/ 391*/
392QWidget *Global::shutdown( bool ) 392QWidget *Global::shutdown( bool )
393{ 393{
394#if !defined(QT_NO_COP) 394#if !defined(QT_NO_COP)
395 QCopChannel::send( "QPE/System", "shutdown()" ); 395 QCopChannel::send( "QPE/System", "shutdown()" );
396#endif 396#endif
397 return 0; 397 return 0;
398} 398}
399 399
400/*! 400/*!
401 \internal 401 \internal
402*/ 402*/
403QWidget *Global::restart( bool ) 403QWidget *Global::restart( bool )
404{ 404{
405#if !defined(QT_NO_COP) 405#if !defined(QT_NO_COP)
406 QCopChannel::send( "QPE/System", "restart()" ); 406 QCopChannel::send( "QPE/System", "restart()" );
407#endif 407#endif
408 return 0; 408 return 0;
409} 409}
410 410
411/*! 411/*!
412 Explicitly show the current input method. 412 Explicitly show the current input method.
413 413
414 Input methods are indicated in the taskbar by a small icon. If the 414 Input methods are indicated in the taskbar by a small icon. If the
415 input method is activated (shown) then it takes up some proportion 415 input method is activated (shown) then it takes up some proportion
416 of the bottom of the screen, to allow the user to interact (input 416 of the bottom of the screen, to allow the user to interact (input
417 characters) with it. 417 characters) with it.
418 418
419 \sa hideInputMethod() 419 \sa hideInputMethod()
420*/ 420*/
421void Global::showInputMethod() 421void Global::showInputMethod()
422{ 422{
423#if !defined(QT_NO_COP) 423#if !defined(QT_NO_COP)
424 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); 424 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" );
425#endif 425#endif
426} 426}
427 427
428/*! 428/*!
429 Explicitly hide the current input method. 429 Explicitly hide the current input method.
430 430
431 The current input method is still indicated in the taskbar, but no 431 The current input method is still indicated in the taskbar, but no
432 longer takes up screen space, and can no longer be interacted with. 432 longer takes up screen space, and can no longer be interacted with.
433 433
434 \sa showInputMethod() 434 \sa showInputMethod()
435*/ 435*/
436void Global::hideInputMethod() 436void Global::hideInputMethod()
437{ 437{
438#if !defined(QT_NO_COP) 438#if !defined(QT_NO_COP)
439 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); 439 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" );
440#endif 440#endif
441} 441}
442 442
443 443
444/*! 444/*!
445 \internal 445 \internal
446*/ 446*/
447bool Global::isBuiltinCommand( const QString &name ) 447bool Global::isBuiltinCommand( const QString &name )
448{ 448{
449 if(!builtin) 449 if(!builtin)
450 return FALSE; // yes, it can happen 450 return FALSE; // yes, it can happen
451 for (int i = 0; builtin[i].file; i++) { 451 for (int i = 0; builtin[i].file; i++) {
452 if ( builtin[i].file == name ) { 452 if ( builtin[i].file == name ) {
453 return TRUE; 453 return TRUE;
454 } 454 }
455 } 455 }
456 return FALSE; 456 return FALSE;
457} 457}
458 458
459Global::Command* Global::builtin=0; 459Global::Command* Global::builtin=0;
460QGuardedPtr<QWidget> *Global::running=0; 460QGuardedPtr<QWidget> *Global::running=0;
461 461
462/*! 462/*!
463 \class Global::Command 463 \class Global::Command
464 \brief The Global::Command class is internal. 464 \brief The Global::Command class is internal.
465 \internal 465 \internal
466*/ 466*/
467 467
468/*! 468/*!
469 \internal 469 \internal
470*/ 470*/
471void Global::setBuiltinCommands( Command* list ) 471void Global::setBuiltinCommands( Command* list )
472{ 472{
473 if ( running ) 473 if ( running )
474 delete [] running; 474 delete [] running;
475 475
476 builtin = list; 476 builtin = list;
477 int count = 0; 477 int count = 0;
478 if (!builtin) 478 if (!builtin)
479 return; 479 return;
480 while ( builtin[count].file ) 480 while ( builtin[count].file )
481 count++; 481 count++;
482 482
483 running = new QGuardedPtr<QWidget> [ count ]; 483 running = new QGuardedPtr<QWidget> [ count ];
484} 484}
485 485
486/*! 486/*!
487 \internal 487 \internal
488*/ 488*/
489void Global::setDocument( QWidget* receiver, const QString& document ) 489void Global::setDocument( QWidget* receiver, const QString& document )
490{ 490{
491 Emitter emitter(receiver,document); 491 Emitter emitter(receiver,document);
492} 492}
493 493
494/*! 494/*!
495 \internal 495 \internal
496*/ 496*/
497bool Global::terminateBuiltin( const QString& n ) 497bool Global::terminateBuiltin( const QString& n )
498{ 498{
499 if (!builtin) 499 if (!builtin)
500 return FALSE; 500 return FALSE;
501 for (int i = 0; builtin[i].file; i++) { 501 for (int i = 0; builtin[i].file; i++) {
502 if ( builtin[i].file == n ) { 502 if ( builtin[i].file == n ) {
503 delete running[i]; 503 delete running[i];
504 return TRUE; 504 return TRUE;
505 } 505 }
506 } 506 }
507 return FALSE; 507 return FALSE;
508} 508}
509 509
510/*! 510/*!
511 \internal 511 \internal
512*/ 512*/
513void Global::terminate( const AppLnk* app ) 513void Global::terminate( const AppLnk* app )
514{ 514{
515 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this 515 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this
516 516
517#ifndef QT_NO_COP 517#ifndef QT_NO_COP
518 QCString channel = "QPE/Application/" + app->exec().utf8(); 518 QCString channel = "QPE/Application/" + app->exec().utf8();
519 if ( QCopChannel::isRegistered(channel) ) { 519 if ( QCopChannel::isRegistered(channel) ) {
520 QCopEnvelope e(channel, "quit()"); 520 QCopEnvelope e(channel, "quit()");
521 } 521 }
522#endif 522#endif
523} 523}
524 524
525/*! 525/*!
526 Low-level function to run command \a c. 526 Low-level function to run command \a c.
527 527
528 \warning Do not use this function. Use execute instead. 528 \warning Do not use this function. Use execute instead.
529 529
530 \sa execute() 530 \sa execute()
531*/ 531*/
532void Global::invoke(const QString &c) 532void Global::invoke(const QString &c)
533{ 533{
534 // Convert the command line in to a list of arguments 534 // Convert the command line in to a list of arguments
535 QStringList list = QStringList::split(QRegExp(" *"),c); 535 QStringList list = QStringList::split(QRegExp(" *"),c);
536 536
537#if !defined(QT_NO_COP) 537#if !defined(QT_NO_COP)
538 QString ap=list[0]; 538 QString ap=list[0];
539 // see if the application is already running 539 // see if the application is already running
540 // XXX should lock file /tmp/qcop-msg-ap 540 // XXX should lock file /tmp/qcop-msg-ap
541 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { 541 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
542 // If the channel is already register, the app is already running, so show it. 542 // If the channel is already register, the app is already running, so show it.
543 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } 543 {
544 544 QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" );
545 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 545 }
546 //e << ap; 546
547 return; 547 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
548 //e << ap;
549 return;
548 } 550 }
549 // XXX should unlock file /tmp/qcop-msg-ap 551 // XXX should unlock file /tmp/qcop-msg-ap
550 //see if it is being started 552 //see if it is being started
551 if ( StartingAppList::isStarting( ap ) ) { 553 if ( StartingAppList::isStarting( ap ) ) {
552 // FIXME take it out for now, since it leads to a much to short showing of wait if 554 // FIXME take it out for now, since it leads to a much to short showing of wait if
553 // some entry is clicked. 555 // some entry is clicked.
554 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes 556 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes
555 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there 557 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there
556 // had the idea that an apploader belongs to the launcher ... 558 // had the idea that an apploader belongs to the launcher ...
557 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 559 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
558 //e << ap; 560 //e << ap;
559 return; 561 return;
560 } 562 }
561 563
562#endif 564#endif
563 565
564#ifdef QT_NO_QWS_MULTIPROCESS 566#ifdef QT_NO_QWS_MULTIPROCESS
565 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); 567 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
566#else 568#else
567 569
568 QStrList slist; 570 QStrList slist;
569 unsigned int j; 571 unsigned int j;
570 for ( j = 0; j < list.count(); j++ ) 572 for ( j = 0; j < list.count(); j++ )
571 slist.append( list[j].utf8() ); 573 slist.append( list[j].utf8() );
572 574
573 const char **args = new const char *[slist.count() + 1]; 575 const char **args = new const char *[slist.count() + 1];
574 for ( j = 0; j < slist.count(); j++ ) 576 for ( j = 0; j < slist.count(); j++ )
575 args[j] = slist.at(j); 577 args[j] = slist.at(j);
578
576 args[j] = NULL; 579 args[j] = NULL;
577 580
578#if !defined(QT_NO_COP) 581#if !defined(QT_NO_COP)
579 // an attempt to show a wait... 582 // an attempt to show a wait...
580 // more logic should be used, but this will be fine for the moment... 583 // more logic should be used, but this will be fine for the moment...
581 QCopEnvelope ( "QPE/System", "busy()" ); 584 QCopEnvelope ( "QPE/System", "busy()" );
582#endif 585#endif
583 586
584#ifdef HAVE_QUICKEXEC 587#ifdef HAVE_QUICKEXEC
585#ifdef Q_OS_MACX 588#ifdef Q_OS_MACX
586 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; 589 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib";
587#else 590#else
588 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; 591 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
589#endif 592#endif
590 qDebug("libfile = %s", libexe.latin1() ); 593 qDebug("libfile = %s", libexe.latin1() );
591 if ( QFile::exists( libexe ) ) { 594 if ( QFile::exists( libexe ) ) {
592 qDebug("calling quickexec %s", libexe.latin1() ); 595 qDebug("calling quickexec %s", libexe.latin1() );
593 quickexecv( libexe.utf8().data(), (const char **)args ); 596 quickexecv( libexe.utf8().data(), (const char **)args );
594 } else 597 } else
595#endif 598#endif
596 { 599 {
597 bool success = false; 600 bool success = false;
598 int pfd [2]; 601 int pfd [2];
599 if ( ::pipe ( pfd ) < 0 ) 602 if ( ::pipe ( pfd ) < 0 )
600 pfd [0] = pfd [1] = -1; 603 pfd [0] = pfd [1] = -1;
601 604
602 pid_t pid = ::fork ( ); 605 pid_t pid = ::fork ( );
603 606
604 if ( pid == 0 ) { // child 607 if ( pid == 0 ) { // child
605 for ( int fd = 3; fd < 100; fd++ ) { 608 for ( int fd = 3; fd < 100; fd++ ) {
606 if ( fd != pfd [1] ) 609 if ( fd != pfd [1] )
607 ::close ( fd ); 610 ::close ( fd );
608 } 611 }
609 ::setpgid ( ::getpid ( ), ::getppid ( )); 612 ::setpgid ( ::getpid ( ), ::getppid ( ));
610 613
611 // Closing of fd[1] indicates that the execvp succeeded! 614 // Closing of fd[1] indicates that the execvp succeeded!
612 if ( pfd [1] >= 0 ) 615 if ( pfd [1] >= 0 )
613 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); 616 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
614 617
615 // Try bindir first, so that foo/bar works too 618 // Try bindir first, so that foo/bar works too
616 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); 619 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
617 ::execvp ( args [0], (char * const *) args ); 620 ::execvp ( args [0], (char * const *) args );
618 621
619 char resultByte = 1; 622 char resultByte = 1;
620 if ( pfd [1] >= 0 ) 623 if ( pfd [1] >= 0 )
621 ::write ( pfd [1], &resultByte, 1 ); 624 ::write ( pfd [1], &resultByte, 1 );
622 ::_exit ( -1 ); 625 ::_exit ( -1 );
623 } 626 }
624 else if ( pid > 0 ) { 627 else if ( pid > 0 ) {
625 success = true; 628 success = true;
626 629
627 if ( pfd [1] >= 0 ) 630 if ( pfd [1] >= 0 )
628 ::close ( pfd [1] ); 631 ::close ( pfd [1] );
629 if ( pfd [0] >= 0 ) { 632 if ( pfd [0] >= 0 ) {
630 while ( true ) { 633 while ( true ) {
631 char resultByte; 634 char resultByte;
632 int n = ::read ( pfd [0], &resultByte, 1 ); 635 int n = ::read ( pfd [0], &resultByte, 1 );
633 if ( n == 1 ) { 636 if ( n == 1 ) {
634 success = false; 637 success = false;
635 break; 638 break;
636 } 639 }
637 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) 640 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
638 continue; 641 continue;
639 642
640 break; // success 643 break; // success
641 } 644 }
642 ::close ( pfd [0] ); 645 ::close ( pfd [0] );
643 } 646 }
644 } 647 }
645 if ( success ) 648 if ( success )
646 StartingAppList::add( list[0] ); 649 StartingAppList::add( list[0] );
647 else 650 else
648 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); 651 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
649 } 652 }
653 delete [] args;
650#endif //QT_NO_QWS_MULTIPROCESS 654#endif //QT_NO_QWS_MULTIPROCESS
651} 655}
652 656
653 657
654/*! 658/*!
655 Executes the application identfied by \a c, passing \a 659 Executes the application identfied by \a c, passing \a
656 document if it isn't null. 660 document if it isn't null.
657 661
658 Note that a better approach might be to send a QCop message to the 662 Note that a better approach might be to send a QCop message to the
659 application's QPE/Application/\e{appname} channel. 663 application's QPE/Application/\e{appname} channel.
660*/ 664*/
661void Global::execute( const QString &c, const QString& document ) 665void Global::execute( const QString &c, const QString& document )
662{ 666{
663 // ask the server to do the work 667 // ask the server to do the work
664#if !defined(QT_NO_COP) 668#if !defined(QT_NO_COP)
665 if ( document.isNull() ) { 669 if ( document.isNull() ) {
666 QCopEnvelope e( "QPE/System", "execute(QString)" ); 670 QCopEnvelope e( "QPE/System", "execute(QString)" );
667 e << c; 671 e << c;
668 } else { 672 } else {
669 QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); 673 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
670 e << c << document; 674 e << c << document;
671 } 675 }
672#endif 676#endif
673 return; 677 return;
674} 678}
675 679
676/*! 680/*!
677 Returns the string \a s with the characters '\', '"', and '$' quoted 681 Returns the string \a s with the characters '\', '"', and '$' quoted
678 by a preceeding '\'. 682 by a preceeding '\'.
679 683
680 \sa stringQuote() 684 \sa stringQuote()
681*/ 685*/
682QString Global::shellQuote(const QString& s) 686QString Global::shellQuote(const QString& s)
683{ 687{
684 QString r="\""; 688 QString r="\"";
685 for (int i=0; i<(int)s.length(); i++) { 689 for (int i=0; i<(int)s.length(); i++) {
686 char c = s[i].latin1(); 690 char c = s[i].latin1();
687 switch (c) { 691 switch (c) {
688 case '\\': case '"': case '$': 692 case '\\': case '"': case '$':
689 r+="\\"; 693 r+="\\";
690 } 694 }
691 r += s[i]; 695 r += s[i];
692 } 696 }
693 r += "\""; 697 r += "\"";
694 return r; 698 return r;
695} 699}
696 700
697/*! 701/*!
698 Returns the string \a s with the characters '\' and '"' quoted by a 702 Returns the string \a s with the characters '\' and '"' quoted by a
699 preceeding '\'. 703 preceeding '\'.
700 704
701 \sa shellQuote() 705 \sa shellQuote()
702*/ 706*/
703QString Global::stringQuote(const QString& s) 707QString Global::stringQuote(const QString& s)
704{ 708{
705 QString r="\""; 709 QString r="\"";
706 for (int i=0; i<(int)s.length(); i++) { 710 for (int i=0; i<(int)s.length(); i++) {
707 char c = s[i].latin1(); 711 char c = s[i].latin1();
708 switch (c) { 712 switch (c) {
709 case '\\': case '"': 713 case '\\': case '"':
710 r+="\\"; 714 r+="\\";
711 } 715 }
712 r += s[i]; 716 r += s[i];
713 } 717 }
714 r += "\""; 718 r += "\"";
715 return r; 719 return r;
716} 720}
717 721
718/*! 722/*!
719 Finds all documents on the system's document directories which 723 Finds all documents on the system's document directories which
720 match the filter \a mimefilter, and appends the resulting DocLnk 724 match the filter \a mimefilter, and appends the resulting DocLnk
721 objects to \a folder. 725 objects to \a folder.
722*/ 726*/
723void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) 727void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
724{ 728{
725 QString homedocs = QString(getenv("HOME")) + "/Documents"; 729 QString homedocs = QString(getenv("HOME")) + "/Documents";
726 DocLnkSet d(homedocs,mimefilter); 730 DocLnkSet d(homedocs,mimefilter);
727 folder->appendFrom(d); 731 folder->appendFrom(d);
728 /** let's do intellegint way of searching these files 732 /** let's do intellegint way of searching these files
729 * a) the user don't want to check mediums global 733 * a) the user don't want to check mediums global
730 * b) the user wants to check but use the global options for it 734 * b) the user wants to check but use the global options for it
731 * c) the user wants to check it but not this medium 735 * c) the user wants to check it but not this medium
732 * d) the user wants to check and this medium as well 736 * d) the user wants to check and this medium as well
733 * 737 *
734 * In all cases we need to apply a different mimefilter to 738 * In all cases we need to apply a different mimefilter to
735 * the medium. 739 * the medium.
736 * a) mimefilter.isEmpty() we need to apply the responding filter 740 * a) mimefilter.isEmpty() we need to apply the responding filter
737 * either the global or the one on the medium 741 * either the global or the one on the medium
738 * 742 *
739 * b) mimefilter is set to an application we need to find out if the 743 * b) mimefilter is set to an application we need to find out if the
740 * mimetypes are included in the mime mask of the medium 744 * mimetypes are included in the mime mask of the medium
741 */ 745 */
742 StorageInfo storage; 746 StorageInfo storage;
743 const QList<FileSystem> &fs = storage.fileSystems(); 747 const QList<FileSystem> &fs = storage.fileSystems();
744 QListIterator<FileSystem> it ( fs ); 748 QListIterator<FileSystem> it ( fs );
745 for ( ; it.current(); ++it ) { 749 for ( ; it.current(); ++it ) {
746 if ( (*it)->isRemovable() ) { // let's find out if we should search on it 750 if ( (*it)->isRemovable() ) { // let's find out if we should search on it
747 // this is a candidate look at the cf and see if we should search on it 751 // this is a candidate look at the cf and see if we should search on it
748 QString path = (*it)->path(); 752 QString path = (*it)->path();
749 Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); 753 Config conf((*it)->path() + "/.opiestorage.cf", Config::File );
750 conf.setGroup("main"); 754 conf.setGroup("main");
751 if (!conf.readBoolEntry("check",true)) { 755 if (!conf.readBoolEntry("check",true)) {
752 continue; 756 continue;
753 } 757 }
754 conf.setGroup("subdirs"); 758 conf.setGroup("subdirs");
755 if (conf.readBoolEntry("wholemedia",true)) { 759 if (conf.readBoolEntry("wholemedia",true)) {
756 DocLnkSet ide( path,mimefilter); 760 DocLnkSet ide( path,mimefilter);
757 folder->appendFrom(ide); 761 folder->appendFrom(ide);
758 } else { 762 } else {
759 QStringList subDirs = conf.readListEntry("subdirs",':'); 763 QStringList subDirs = conf.readListEntry("subdirs",':');
760 if (subDirs.isEmpty()) { 764 if (subDirs.isEmpty()) {
761 subDirs.append("Documents"); 765 subDirs.append("Documents");
762 } 766 }
763 for (unsigned c = 0; c < subDirs.count();++c) { 767 for (unsigned c = 0; c < subDirs.count();++c) {
764 DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); 768 DocLnkSet ide( path+"/"+subDirs[c], mimefilter );
765 folder->appendFrom(ide); 769 folder->appendFrom(ide);
766 } 770 }
767 } 771 }
768 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { 772 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
769 QString path = (*it)->path() + "/Documents"; 773 QString path = (*it)->path() + "/Documents";
770 DocLnkSet ide( path, mimefilter ); 774 DocLnkSet ide( path, mimefilter );
771 folder->appendFrom(ide); 775 folder->appendFrom(ide);
772 } 776 }
773 } 777 }
774} 778}
775 779
776QStringList Global::languageList() 780QStringList Global::languageList()
777{ 781{
778 QString lang = getenv("LANG"); 782 QString lang = getenv("LANG");
779 QStringList langs; 783 QStringList langs;
780 langs.append(lang); 784 langs.append(lang);
781 int i = lang.find("."); 785 int i = lang.find(".");
782 if ( i > 0 ) 786 if ( i > 0 )
783 lang = lang.left( i ); 787 lang = lang.left( i );
784 i = lang.find( "_" ); 788 i = lang.find( "_" );
785 if ( i > 0 ) 789 if ( i > 0 )
786 langs.append(lang.left(i)); 790 langs.append(lang.left(i));
787 return langs; 791 return langs;
788} 792}
789 793
790QStringList Global::helpPath() 794QStringList Global::helpPath()
791{ 795{
792 QString qpeDir = QPEApplication::qpeDir(); 796 QString qpeDir = QPEApplication::qpeDir();
793 QStringList path; 797 QStringList path;
794 QStringList langs = Global::languageList(); 798 QStringList langs = Global::languageList();
795 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { 799 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
796 QString lang = *it; 800 QString lang = *it;
797 if ( !lang.isEmpty() ) 801 if ( !lang.isEmpty() )
798 path += qpeDir + "/help/" + lang + "/html"; 802 path += qpeDir + "/help/" + lang + "/html";
799 } 803 }
800 path += qpeDir + "/pics"; 804 path += qpeDir + "/pics";
801 path += qpeDir + "/help/html"; 805 path += qpeDir + "/help/html";
802 /* we even put english into the en dir so try it as fallback as well for opie */ 806 /* we even put english into the en dir so try it as fallback as well for opie */
803 path += qpeDir + "/help/en/html"; 807 path += qpeDir + "/help/en/html";
804 path += qpeDir + "/docs"; 808 path += qpeDir + "/docs";
805 809
806 810
807 return path; 811 return path;
808} 812}
809 813
810/*! 814/*!
811 \internal 815 \internal
812 Truncate file to size specified 816 Truncate file to size specified
813 \a f must be an open file 817 \a f must be an open file
814 \a size must be a positive value 818 \a size must be a positive value
815 */ 819 */
816bool Global::truncateFile(QFile &f, int size){ 820bool Global::truncateFile(QFile &f, int size){
817 if (!f.isOpen()) 821 if (!f.isOpen())
818 return FALSE; 822 return FALSE;
819 823
820 return ::ftruncate(f.handle(), size) != -1; 824 return ::ftruncate(f.handle(), size) != -1;
821} 825}
822 826
823 827
824 828
825 829
826// #if defined(Q_OS_UNIX) && defined(Q_WS_QWS) 830// #if defined(Q_OS_UNIX) && defined(Q_WS_QWS)
827// extern int qws_display_id; 831// extern int qws_display_id;
828// #endif 832// #endif
829 833
830/*! 834/*!
831 /internal 835 /internal
832 Returns the default system path for storing temporary files. 836 Returns the default system path for storing temporary files.
833 Note: This does not it ensure that the provided directory exists 837 Note: This does not it ensure that the provided directory exists
834*/ 838*/
835QString Global::tempDir() 839QString Global::tempDir()
836{ 840{
837 QString result; 841 QString result;
838#ifdef Q_OS_UNIX 842#ifdef Q_OS_UNIX
839#ifdef Q_WS_QWS 843#ifdef Q_WS_QWS
840 result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id)); 844 result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id));
841#else 845#else
842 result="/tmp/"; 846 result="/tmp/";
843#endif 847#endif
844#else 848#else
845 if (getenv("TEMP")) 849 if (getenv("TEMP"))
846 result = getenv("TEMP"); 850 result = getenv("TEMP");
847 else 851 else
848 result = getenv("TMP"); 852 result = getenv("TMP");
849 853
850 if (result[(int)result.length() - 1] != QDir::separator()) 854 if (result[(int)result.length() - 1] != QDir::separator())
851 result.append(QDir::separator()); 855 result.append(QDir::separator());
852#endif 856#endif
853 857
854 return result; 858 return result;
855} 859}
856 860
857//#endif 861//#endif
858 862
859 863
860#include "global.moc" 864#include "global.moc"
diff --git a/noncore/apps/opie-reader/Bkmks.cpp b/noncore/apps/opie-reader/Bkmks.cpp
index 00141a3..45aa045 100644
--- a/noncore/apps/opie-reader/Bkmks.cpp
+++ b/noncore/apps/opie-reader/Bkmks.cpp
@@ -1,416 +1,417 @@
1#include <qmessagebox.h> 1#include <qmessagebox.h>
2 2
3#include "Bkmks.h" 3#include "Bkmks.h"
4 4
5#include "StyleConsts.h" 5#include "StyleConsts.h"
6#include "Markups.h" 6#include "Markups.h"
7#include "my_list.h" 7#include "my_list.h"
8#include "version.h" 8#include "version.h"
9#include "names.h" 9#include "names.h"
10 10
11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); 11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE);
12 12
13Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : 13Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) :
14 m_name(0), 14 m_name(0),
15 m_namelen(0), 15 m_namelen(0),
16 m_anno(0), 16 m_anno(0),
17 m_annolen(0), 17 m_annolen(0),
18 m_position(0) 18 m_position(0)
19{ 19{
20 init(_nm, _nmlen, _anno, _annolen, _p); 20 init(_nm, _nmlen, _anno, _annolen, _p);
21} 21}
22 22
23Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) 23Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p)
24{ 24{
25 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p); 25 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p);
26} 26}
27 27
28Bkmk::Bkmk(const Bkmk& rhs) : 28Bkmk::Bkmk(const Bkmk& rhs) :
29 m_name(0), 29 m_name(0),
30 m_namelen(0), 30 m_namelen(0),
31 m_anno(0), 31 m_anno(0),
32 m_annolen(0), 32 m_annolen(0),
33 m_position(0) 33 m_position(0)
34{ 34{
35 init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(), 35 init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(),
36 sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value()); 36 sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value());
37} 37}
38 38
39Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) 39Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p)
40{ 40{
41 if (_anno == NULL) 41 if (_anno == NULL)
42 { 42 {
43 tchar t = 0; 43 tchar t = 0;
44 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); 44 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p);
45 } 45 }
46 else 46 else
47 { 47 {
48 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); 48 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p);
49 } 49 }
50} 50}
51 51
52Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) 52Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p)
53{ 53{
54 if (_anno == NULL) 54 if (_anno == NULL)
55 { 55 {
56 tchar t = 0; 56 tchar t = 0;
57 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); 57 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p);
58 } 58 }
59 else 59 else
60 { 60 {
61 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); 61 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p);
62 } 62 }
63 m_position2 = _p2; 63 m_position2 = _p2;
64 m_red = m_green = m_blue = 127; 64 m_red = m_green = m_blue = 127;
65} 65}
66 66
67void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) 67void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p)
68{ 68{
69 m_namelen = _nmlen; 69 m_namelen = _nmlen;
70 if (m_namelen > 0) 70 if (m_namelen > 0)
71 { 71 {
72 m_name = new unsigned char[m_namelen]; 72 m_name = new unsigned char[m_namelen];
73 memcpy(m_name, _nm, m_namelen); 73 memcpy(m_name, _nm, m_namelen);
74 } 74 }
75 else 75 else
76 { 76 {
77 m_name = NULL; 77 m_name = NULL;
78 } 78 }
79 79
80 m_annolen = _annolen; 80 m_annolen = _annolen;
81 if (m_annolen > 0) 81 if (m_annolen > 0)
82 { 82 {
83 m_anno = new unsigned char[m_annolen]; 83 m_anno = new unsigned char[m_annolen];
84 memcpy(m_anno, _anno, m_annolen); 84 memcpy(m_anno, _anno, m_annolen);
85 } 85 }
86 else 86 else
87 { 87 {
88 m_anno = NULL; 88 m_anno = NULL;
89 } 89 }
90 m_position = _p; 90 m_position = _p;
91 m_position2 = _p; 91 m_position2 = _p;
92 m_red = m_green = m_blue = 255; 92 m_red = m_green = m_blue = 255;
93 m_level = 0; 93 m_level = 0;
94} 94}
95 95
96Bkmk::~Bkmk() 96Bkmk::~Bkmk()
97{ 97{
98 if (m_name != NULL) delete [] m_name; 98 if (m_name != NULL) delete [] m_name;
99 m_name = NULL; 99 m_name = NULL;
100 if (m_anno != NULL) delete [] m_anno; 100 if (m_anno != NULL) delete [] m_anno;
101 m_anno = NULL; 101 m_anno = NULL;
102} 102}
103 103
104Bkmk& Bkmk::operator=(const Bkmk& rhs) 104Bkmk& Bkmk::operator=(const Bkmk& rhs)
105{ 105{
106 if (m_name != NULL) 106 if (m_name != NULL)
107 { 107 {
108 delete [] m_name; 108 delete [] m_name;
109 m_name = NULL; 109 m_name = NULL;
110 } 110 }
111 if (m_anno != NULL) 111 if (m_anno != NULL)
112 { 112 {
113 delete [] m_anno; 113 delete [] m_anno;
114 m_anno = NULL; 114 m_anno = NULL;
115 } 115 }
116 if (rhs.m_name != NULL) 116 if (rhs.m_name != NULL)
117 { 117 {
118 m_namelen = rhs.m_namelen; 118 m_namelen = rhs.m_namelen;
119 m_name = new unsigned char[m_namelen]; 119 m_name = new unsigned char[m_namelen];
120 memcpy(m_name, rhs.m_name, m_namelen); 120 memcpy(m_name, rhs.m_name, m_namelen);
121 } 121 }
122 else 122 else
123 m_name = NULL; 123 m_name = NULL;
124 if (rhs.m_anno != NULL) 124 if (rhs.m_anno != NULL)
125 { 125 {
126 m_annolen = rhs.m_annolen; 126 m_annolen = rhs.m_annolen;
127 m_anno = new unsigned char[m_annolen]; 127 m_anno = new unsigned char[m_annolen];
128 memcpy(m_anno, rhs.m_anno, m_annolen); 128 memcpy(m_anno, rhs.m_anno, m_annolen);
129 } 129 }
130 else 130 else
131 m_anno = NULL; 131 m_anno = NULL;
132 m_position = rhs.m_position; 132 m_position = rhs.m_position;
133 m_position2 = rhs.m_position2; 133 m_position2 = rhs.m_position2;
134 m_red = rhs.m_red; 134 m_red = rhs.m_red;
135 m_green = rhs.m_green; 135 m_green = rhs.m_green;
136 m_blue = rhs.m_blue; 136 m_blue = rhs.m_blue;
137 m_level = rhs.m_level; 137 m_level = rhs.m_level;
138 return *this; 138 return *this;
139} 139}
140 140
141bool Bkmk::operator==(const Bkmk& rhs) 141bool Bkmk::operator==(const Bkmk& rhs)
142{ 142{
143 return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0); 143 return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0);
144} 144}
145 145
146void Bkmk::setAnno(unsigned char* t, unsigned short len) 146void Bkmk::setAnno(unsigned char* t, unsigned short len)
147{ 147{
148 if (m_anno != NULL) 148 if (m_anno != NULL)
149 { 149 {
150 delete [] m_anno; 150 delete [] m_anno;
151 m_anno = NULL; 151 m_anno = NULL;
152 } 152 }
153 if (t != NULL) 153 if (t != NULL)
154 { 154 {
155 m_annolen = len; 155 m_annolen = len;
156 m_anno = new unsigned char[m_annolen]; 156 m_anno = new unsigned char[m_annolen];
157 memcpy(m_anno, t, m_annolen); 157 memcpy(m_anno, t, m_annolen);
158 } 158 }
159 else 159 else
160 { 160 {
161 m_annolen = sizeof(tchar); 161 m_annolen = sizeof(tchar);
162 m_anno = new unsigned char[m_annolen]; 162 m_anno = new unsigned char[m_annolen];
163 *((tchar*)m_anno) = 0; 163 *((tchar*)m_anno) = 0;
164 } 164 }
165} 165}
166 166
167void Bkmk::setAnno(tchar* t) 167void Bkmk::setAnno(tchar* t)
168{ 168{
169 if (m_anno != NULL) 169 if (m_anno != NULL)
170 { 170 {
171 delete [] m_anno; 171 delete [] m_anno;
172 m_anno = NULL; 172 m_anno = NULL;
173 } 173 }
174 if (t != NULL) 174 if (t != NULL)
175 { 175 {
176 unsigned short len = ustrlen(t)+1; 176 unsigned short len = ustrlen(t)+1;
177 m_annolen = sizeof(tchar)*len; 177 m_annolen = sizeof(tchar)*len;
178 m_anno = new unsigned char[m_annolen]; 178 m_anno = new unsigned char[m_annolen];
179 memcpy(m_anno, t, m_annolen); 179 memcpy(m_anno, t, m_annolen);
180 } 180 }
181 else 181 else
182 { 182 {
183 m_annolen = sizeof(tchar); 183 m_annolen = sizeof(tchar);
184 m_anno = new unsigned char[m_annolen]; 184 m_anno = new unsigned char[m_annolen];
185 *((tchar*)m_anno) = 0; 185 *((tchar*)m_anno) = 0;
186 } 186 }
187} 187}
188 188
189BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) 189BkmkFile::BkmkFile(const char *fnm, bool w, bool _x)
190 : 190 :
191 wt(w), isUpgraded(false), m_extras(_x) 191 wt(w), isUpgraded(false), m_extras(_x)
192{ 192{
193 if (w) 193 if (w)
194 { 194 {
195 f = fopen(fnm, "wb"); 195 f = fopen(fnm, "wb");
196 } 196 }
197 else 197 else
198 { 198 {
199 f = fopen(fnm, "rb"); 199 f = fopen(fnm, "rb");
200 } 200 }
201} 201}
202 202
203BkmkFile::~BkmkFile() 203BkmkFile::~BkmkFile()
204{ 204{
205 if (f != NULL) fclose(f); 205 if (f != NULL) fclose(f);
206} 206}
207 207
208void BkmkFile::write(const Bkmk& b) 208void BkmkFile::write(const Bkmk& b)
209{ 209{
210 if (f != NULL) 210 if (f != NULL)
211 { 211 {
212 fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f); 212 fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f);
213 fwrite(b.m_name,1,b.m_namelen,f); 213 fwrite(b.m_name,1,b.m_namelen,f);
214 fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f); 214 fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f);
215 fwrite(b.m_anno,1,b.m_annolen,f); 215 fwrite(b.m_anno,1,b.m_annolen,f);
216 fwrite(&b.m_position,sizeof(b.m_position),1,f); 216 fwrite(&b.m_position,sizeof(b.m_position),1,f);
217 if (m_extras) 217 if (m_extras)
218 { 218 {
219 fwrite(&b.m_position2,sizeof(b.m_position2),1,f); 219 fwrite(&b.m_position2,sizeof(b.m_position2),1,f);
220 fwrite(&b.m_red,sizeof(b.m_red),1,f); 220 fwrite(&b.m_red,sizeof(b.m_red),1,f);
221 fwrite(&b.m_green,sizeof(b.m_green),1,f); 221 fwrite(&b.m_green,sizeof(b.m_green),1,f);
222 fwrite(&b.m_blue,sizeof(b.m_blue),1,f); 222 fwrite(&b.m_blue,sizeof(b.m_blue),1,f);
223 fwrite(&b.m_level,sizeof(b.m_level),1,f); 223 fwrite(&b.m_level,sizeof(b.m_level),1,f);
224 } 224 }
225 } 225 }
226} 226}
227 227
228void BkmkFile::write(CList<Bkmk>& bl) 228void BkmkFile::write(CList<Bkmk>& bl)
229{ 229{
230 if (f != NULL) 230 if (f != NULL)
231 { 231 {
232 fwrite(&magic, sizeof(magic), 1, f); 232 fwrite(&magic, sizeof(magic), 1, f);
233 for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++) 233 for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++)
234 { 234 {
235 write(*i); 235 write(*i);
236 } 236 }
237 } 237 }
238} 238}
239 239
240CList<Bkmk>* BkmkFile::readall() 240CList<Bkmk>* BkmkFile::readall()
241{ 241{
242 CList<Bkmk>* bl = NULL; 242 CList<Bkmk>* bl = NULL;
243 if (f != NULL) 243 if (f != NULL)
244 { 244 {
245 unsigned long newmagic; 245 unsigned long newmagic;
246 fread(&newmagic, sizeof(newmagic), 1, f); 246 fread(&newmagic, sizeof(newmagic), 1, f);
247 if ((newmagic & 0xffffff00) != (magic & 0xffffff00)) 247 if ((newmagic & 0xffffff00) != (magic & 0xffffff00))
248 { 248 {
249 if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0) 249 if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0)
250 { 250 {
251 fseek(f,0,SEEK_SET); 251 fseek(f,0,SEEK_SET);
252 bl = readall00(&read05); 252 bl = readall00(&read05);
253 } 253 }
254 else 254 else
255 { 255 {
256 fseek(f,0,SEEK_SET); 256 fseek(f,0,SEEK_SET);
257 bl = readall00(&read03); 257 bl = readall00(&read03);
258 } 258 }
259 isUpgraded = true; 259 isUpgraded = true;
260 } 260 }
261 else 261 else
262 { 262 {
263 switch(newmagic & 0xff) 263 switch(newmagic & 0xff)
264 { 264 {
265 case 7: 265 case 7:
266 isUpgraded = false; 266 isUpgraded = false;
267 bl = readall00(read07); 267 bl = readall00(read07);
268 // qDebug("Correct version!"); 268 // qDebug("Correct version!");
269 break; 269 break;
270 case 6: 270 case 6:
271 isUpgraded = true; 271 isUpgraded = true;
272 bl = readall00(read06); 272 bl = readall00(read06);
273 // qDebug("Correct version!"); 273 // qDebug("Correct version!");
274 break; 274 break;
275 case 5: 275 case 5:
276 isUpgraded = true; 276 isUpgraded = true;
277 bl = readall00(read05); 277 bl = readall00(read05);
278 // qDebug("Known version!"); 278 // qDebug("Known version!");
279 break; 279 break;
280 default: 280 default:
281 // qDebug("Unknown version!"); 281 // qDebug("Unknown version!");
282 isUpgraded = true; 282 isUpgraded = true;
283 bl = readall00(read05); 283 bl = readall00(read05);
284 } 284 }
285 } 285 }
286 } 286 }
287 return bl; 287 return bl;
288} 288}
289 289
290CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) 290CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*))
291{ 291{
292 CList<Bkmk>* bl = new CList<Bkmk>; 292 CList<Bkmk>* bl = new CList<Bkmk>;
293 while (1) 293 while (1)
294 { 294 {
295 Bkmk* b = (*readfn)(this, f); 295 Bkmk* b = (*readfn)(this, f);
296 if (b == NULL) break; 296 if (b == NULL) break;
297 bl->push_back(*b); 297 bl->push_back(*b);
298 delete b; 298 delete b;
299 } 299 }
300 return bl; 300 return bl;
301} 301}
302 302
303Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) 303Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f)
304{ 304{
305 Bkmk* b = NULL; 305 Bkmk* b = NULL;
306 if (f != NULL) 306 if (f != NULL)
307 { 307 {
308 unsigned short ln; 308 unsigned short ln;
309 if (fread(&ln,sizeof(ln),1,f) == 1) 309 if (fread(&ln,sizeof(ln),1,f) == 1)
310 { 310 {
311 tchar* name = new tchar[ln+1]; 311 tchar* name = new tchar[ln+1];
312 fread(name,sizeof(tchar),ln,f); 312 fread(name,sizeof(tchar),ln,f);
313 name[ln] = 0; 313 name[ln] = 0;
314 314
315 ln = 0; 315 ln = 0;
316 tchar* anno = new tchar[ln+1]; 316 tchar* anno = new tchar[ln+1];
317 anno[ln] = 0; 317 anno[ln] = 0;
318 318
319 unsigned int pos; 319 unsigned int pos;
320 fread(&pos,sizeof(pos),1,f); 320 fread(&pos,sizeof(pos),1,f);
321 b = new Bkmk(name,anno,pos); 321 b = new Bkmk(name,anno,pos);
322 delete [] anno; 322 delete [] anno;
323 } 323 }
324 } 324 }
325 return b; 325 return b;
326} 326}
327 327
328Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) 328Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f)
329{ 329{
330 Bkmk* b = NULL; 330 Bkmk* b = NULL;
331 if (f != NULL) 331 if (f != NULL)
332 { 332 {
333 unsigned short ln; 333 unsigned short ln;
334 if (fread(&ln,sizeof(ln),1,f) == 1) 334 if (fread(&ln,sizeof(ln),1,f) == 1)
335 { 335 {
336 tchar* nm = new tchar[ln+1]; 336 tchar* nm = new tchar[ln+1];
337 fread(nm,sizeof(tchar),ln,f); 337 fread(nm,sizeof(tchar),ln,f);
338 nm[ln] = 0; 338 nm[ln] = 0;
339 fread(&ln,sizeof(ln),1,f); 339 fread(&ln,sizeof(ln),1,f);
340 tchar* anno = new tchar[ln+1]; 340 tchar* anno = new tchar[ln+1];
341 if (ln > 0) fread(anno,sizeof(tchar),ln,f); 341 if (ln > 0) fread(anno,sizeof(tchar),ln,f);
342 anno[ln] = 0; 342 anno[ln] = 0;
343 unsigned int pos; 343 unsigned int pos;
344 fread(&pos,sizeof(pos),1,f); 344 fread(&pos,sizeof(pos),1,f);
345 b = new Bkmk(nm,anno,pos); 345 b = new Bkmk(nm,anno,pos);
346 delete [] anno;
346 } 347 }
347 } 348 }
348 return b; 349 return b;
349} 350}
350 351
351Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) 352Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f)
352{ 353{
353 Bkmk* b = NULL; 354 Bkmk* b = NULL;
354 if (f != NULL) 355 if (f != NULL)
355 { 356 {
356 unsigned short ln; 357 unsigned short ln;
357 if (fread(&ln,sizeof(ln),1,f) == 1) 358 if (fread(&ln,sizeof(ln),1,f) == 1)
358 { 359 {
359 b = new Bkmk; 360 b = new Bkmk;
360 b->m_namelen = ln; 361 b->m_namelen = ln;
361 b->m_name = new unsigned char[b->m_namelen]; 362 b->m_name = new unsigned char[b->m_namelen];
362 fread(b->m_name,1,b->m_namelen,f); 363 fread(b->m_name,1,b->m_namelen,f);
363 364
364 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); 365 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f);
365 if (b->m_annolen > 0) 366 if (b->m_annolen > 0)
366 { 367 {
367 b->m_anno = new unsigned char[b->m_annolen]; 368 b->m_anno = new unsigned char[b->m_annolen];
368 fread(b->m_anno,1,b->m_annolen,f); 369 fread(b->m_anno,1,b->m_annolen,f);
369 } 370 }
370 fread(&(b->m_position),sizeof(b->m_position),1,f); 371 fread(&(b->m_position),sizeof(b->m_position),1,f);
371 b->m_position2 = b->m_position+b->m_namelen-1; 372 b->m_position2 = b->m_position+b->m_namelen-1;
372 b->m_red = b->m_green = b->m_blue = 127; 373 b->m_red = b->m_green = b->m_blue = 127;
373 b->m_level = 0; 374 b->m_level = 0;
374 } 375 }
375 } 376 }
376 return b; 377 return b;
377} 378}
378 379
379Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) 380Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f)
380{ 381{
381 Bkmk* b = NULL; 382 Bkmk* b = NULL;
382 if (f != NULL) 383 if (f != NULL)
383 { 384 {
384 unsigned short ln; 385 unsigned short ln;
385 if (fread(&ln,sizeof(ln),1,f) == 1) 386 if (fread(&ln,sizeof(ln),1,f) == 1)
386 { 387 {
387 b = new Bkmk; 388 b = new Bkmk;
388 b->m_namelen = ln; 389 b->m_namelen = ln;
389 b->m_name = new unsigned char[b->m_namelen]; 390 b->m_name = new unsigned char[b->m_namelen];
390 fread(b->m_name,1,b->m_namelen,f); 391 fread(b->m_name,1,b->m_namelen,f);
391 392
392 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); 393 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f);
393 if (b->m_annolen > 0) 394 if (b->m_annolen > 0)
394 { 395 {
395 b->m_anno = new unsigned char[b->m_annolen]; 396 b->m_anno = new unsigned char[b->m_annolen];
396 fread(b->m_anno,1,b->m_annolen,f); 397 fread(b->m_anno,1,b->m_annolen,f);
397 } 398 }
398 fread(&(b->m_position),sizeof(b->m_position),1,f); 399 fread(&(b->m_position),sizeof(b->m_position),1,f);
399 if (_this->m_extras) 400 if (_this->m_extras)
400 { 401 {
401 fread(&(b->m_position2),sizeof(b->m_position2),1,f); 402 fread(&(b->m_position2),sizeof(b->m_position2),1,f);
402 fread(&(b->m_red),sizeof(b->m_red),1,f); 403 fread(&(b->m_red),sizeof(b->m_red),1,f);
403 fread(&(b->m_green),sizeof(b->m_green),1,f); 404 fread(&(b->m_green),sizeof(b->m_green),1,f);
404 fread(&(b->m_blue),sizeof(b->m_blue),1,f); 405 fread(&(b->m_blue),sizeof(b->m_blue),1,f);
405 fread(&(b->m_level),sizeof(b->m_level),1,f); 406 fread(&(b->m_level),sizeof(b->m_level),1,f);
406 } 407 }
407 else 408 else
408 { 409 {
409 b->m_position2 = b->m_position; 410 b->m_position2 = b->m_position;
410 b->m_red = b->m_green = b->m_blue = 255; 411 b->m_red = b->m_green = b->m_blue = 255;
411 b->m_level = 0; 412 b->m_level = 0;
412 } 413 }
413 } 414 }
414 } 415 }
415 return b; 416 return b;
416} 417}
diff --git a/noncore/apps/opie-sheet/Excel.cpp b/noncore/apps/opie-sheet/Excel.cpp
index 51fe707..27080e9 100644
--- a/noncore/apps/opie-sheet/Excel.cpp
+++ b/noncore/apps/opie-sheet/Excel.cpp
@@ -1,1709 +1,1711 @@
1/* 1/*
2 =. This file is part of the Opie Project 2 =. This file is part of the Opie Project
3 .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> 3 .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org>
4 .>+-= 4 .>+-=
5 _;:, .> :=|. This program is free software; you can 5 _;:, .> :=|. This program is free software; you can
6.> <`_, > . <= redistribute it and/or modify it under 6.> <`_, > . <= redistribute it and/or modify it under
7:`=1 )Y*s>-.-- : the terms of the GNU General Public 7:`=1 )Y*s>-.-- : the terms of the GNU General Public
8.="- .-=="i, .._ License as published by the Free Software 8.="- .-=="i, .._ License as published by the Free Software
9 - . .-<_> .<> Foundation; either version 2 of the License, 9 - . .-<_> .<> Foundation; either version 2 of the License,
10 ._= =} : or (at your option) any later version. 10 ._= =} : or (at your option) any later version.
11 .%`+i> _;_. 11 .%`+i> _;_.
12 .i_,=:_. -<s. This program is distributed in the hope that 12 .i_,=:_. -<s. This program is distributed in the hope that
13 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 13 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
14 : .. .:, . . . without even the implied warranty of 14 : .. .:, . . . without even the implied warranty of
15 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 15 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
16 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 16 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
17..}^=.= = ; Library General Public License for more 17..}^=.= = ; Library General Public License for more
18++= -. .` .: details. 18++= -. .` .: details.
19 : = ...= . :.=- 19 : = ...= . :.=-
20 -. .:....=;==+<; You should have received a copy of the GNU 20 -. .:....=;==+<; You should have received a copy of the GNU
21 -_. . . )=. = Library General Public License along with 21 -_. . . )=. = Library General Public License along with
22 -- :-=` this library; see the file COPYING.LIB. 22 -- :-=` this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation, 23 If not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330, 24 Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA. 25 Boston, MA 02111-1307, USA.
26 26
27*/ 27*/
28 28
29#include "Excel.h" 29#include "Excel.h"
30 30
31/* STD */ 31/* STD */
32#include <stdio.h> 32#include <stdio.h>
33#include <stdlib.h> 33#include <stdlib.h>
34#include <math.h> 34#include <math.h>
35#include <time.h> 35#include <time.h>
36#include <sys/types.h> 36#include <sys/types.h>
37#include <strings.h> 37#include <strings.h>
38 38
39static xfrecord formatter[] = { 39static xfrecord formatter[] = {
40 { 0xe , DATEFORMAT, "%m/%d/%y"}, 40 { 0xe , DATEFORMAT, "%m/%d/%y"},
41 { 0xf , DATEFORMAT, "%d-%b-%y"}, 41 { 0xf , DATEFORMAT, "%d-%b-%y"},
42 { 0x10, DATEFORMAT, "%d-%b"}, 42 { 0x10, DATEFORMAT, "%d-%b"},
43 { 0x11, DATEFORMAT, "%b-%y"}, 43 { 0x11, DATEFORMAT, "%b-%y"},
44 { 0x12, DATEFORMAT, "%I:%M %p"}, 44 { 0x12, DATEFORMAT, "%I:%M %p"},
45 { 0x13, DATEFORMAT, "%I:%M:%S %p"}, 45 { 0x13, DATEFORMAT, "%I:%M:%S %p"},
46 { 0x14, DATEFORMAT, "%H:%M"}, 46 { 0x14, DATEFORMAT, "%H:%M"},
47 { 0x15, DATEFORMAT, "%H:%M:%S"}, 47 { 0x15, DATEFORMAT, "%H:%M:%S"},
48 { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"}, 48 { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"},
49 { 0x2d, DATEFORMAT, "%M:%S"}, 49 { 0x2d, DATEFORMAT, "%M:%S"},
50 { 0x2e, DATEFORMAT, "%H:%M:%S"}, 50 { 0x2e, DATEFORMAT, "%H:%M:%S"},
51 { 0x2f, DATEFORMAT, "%M:%S"}, 51 { 0x2f, DATEFORMAT, "%M:%S"},
52 { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"}, 52 { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"},
53 { 0x1 , NUMBERFORMAT, "%.0f"}, 53 { 0x1 , NUMBERFORMAT, "%.0f"},
54 { 0x2 , NUMBERFORMAT, "%.2f"}, 54 { 0x2 , NUMBERFORMAT, "%.2f"},
55 { 0x3 , NUMBERFORMAT, "#,##%.0f"}, 55 { 0x3 , NUMBERFORMAT, "#,##%.0f"},
56 { 0x4 , NUMBERFORMAT, "#,##%.2f"}, 56 { 0x4 , NUMBERFORMAT, "#,##%.2f"},
57 { 0x5 , NUMBERFORMAT, "$#,##%.0f"}, 57 { 0x5 , NUMBERFORMAT, "$#,##%.0f"},
58 { 0x6 , NUMBERFORMAT, "$#,##%.0f"}, 58 { 0x6 , NUMBERFORMAT, "$#,##%.0f"},
59 { 0x7 , NUMBERFORMAT, "$#,##%.2f"}, 59 { 0x7 , NUMBERFORMAT, "$#,##%.2f"},
60 { 0x8 , NUMBERFORMAT, "$#,##%.2f"}, 60 { 0x8 , NUMBERFORMAT, "$#,##%.2f"},
61 { 0x9 , NUMBERFORMAT, "%.0f%%"}, 61 { 0x9 , NUMBERFORMAT, "%.0f%%"},
62 { 0xa , NUMBERFORMAT, "%.2f%%"}, 62 { 0xa , NUMBERFORMAT, "%.2f%%"},
63 { 0xb , NUMBERFORMAT, "%e"}, 63 { 0xb , NUMBERFORMAT, "%e"},
64 { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, 64 { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
65 { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, 65 { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
66 { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, 66 { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
67 { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, 67 { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
68 { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, 68 { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
69 { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"}, 69 { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"},
70 { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, 70 { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
71 { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"}, 71 { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"},
72 { 0x30, NUMBERFORMAT, "##0.0E0"}, 72 { 0x30, NUMBERFORMAT, "##0.0E0"},
73 { 0, 0, ""} 73 { 0, 0, ""}
74 }; 74 };
75 75
76 76
77 77
78int ExcelBook::Integer2Byte(int b1, int b2) 78int ExcelBook::Integer2Byte(int b1, int b2)
79{ 79{
80 int i1 = b1 & 0xff; 80 int i1 = b1 & 0xff;
81 int i2 = b2 & 0xff; 81 int i2 = b2 & 0xff;
82 int val = i2 << 8 | i1; 82 int val = i2 << 8 | i1;
83 return val; 83 return val;
84}; 84};
85 85
86int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) 86int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4)
87{ 87{
88 int i1 = Integer2Byte(b1, b2); 88 int i1 = Integer2Byte(b1, b2);
89 int i2 = Integer2Byte(b3, b4); 89 int i2 = Integer2Byte(b3, b4);
90 int val = i2 << 16 | i1; 90 int val = i2 << 16 | i1;
91 return val; 91 return val;
92}; 92};
93 93
94int ExcelBook::Integer2ByteFile(FILE *f) 94int ExcelBook::Integer2ByteFile(FILE *f)
95{ 95{
96 int i1, i2; 96 int i1, i2;
97 i1 = fgetc(f); 97 i1 = fgetc(f);
98 i2 = fgetc(f); 98 i2 = fgetc(f);
99 return Integer2Byte(i1,i2); 99 return Integer2Byte(i1,i2);
100}; 100};
101 101
102float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) 102float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4)
103{ 103{
104 int i; 104 int i;
105 float f; 105 float f;
106 unsigned char *ieee; 106 unsigned char *ieee;
107 ieee = (unsigned char *) &f; 107 ieee = (unsigned char *) &f;
108 for (i = 0; i < 4; i++) ieee[i] = 0; 108 for (i = 0; i < 4; i++) ieee[i] = 0;
109 ieee[0] = ((int)b4) & 0xff; 109 ieee[0] = ((int)b4) & 0xff;
110 ieee[1] = ((int)b3) & 0xff; 110 ieee[1] = ((int)b3) & 0xff;
111 ieee[2] = ((int)b2) & 0xff; 111 ieee[2] = ((int)b2) & 0xff;
112 ieee[3] = ((int)b1) & 0xff; 112 ieee[3] = ((int)b1) & 0xff;
113 return f; 113 return f;
114}; 114};
115 115
116double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) 116double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4)
117{ 117{
118 long int rk; 118 long int rk;
119 double value; 119 double value;
120 120
121 rk=Integer4Byte(b1,b2,b3,b4); 121 rk=Integer4Byte(b1,b2,b3,b4);
122 //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4); 122 //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4);
123 if ( (rk & 0x02) != 0) 123 if ( (rk & 0x02) != 0)
124 { 124 {
125 long int intval = rk >> 2; //drops the 2 bits 125 long int intval = rk >> 2; //drops the 2 bits
126 printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2); 126 printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2);
127 value = (double) intval; 127 value = (double) intval;
128 printf("Double4Byte: VALUEINT=%f\r\n",value); 128 printf("Double4Byte: VALUEINT=%f\r\n",value);
129 if ( (rk & 0x01) != 0) 129 if ( (rk & 0x01) != 0)
130 { 130 {
131 value /= 100.0; 131 value /= 100.0;
132 }; 132 };
133 return value; 133 return value;
134 } 134 }
135 else 135 else
136 { 136 {
137 137
138 union { double d; unsigned long int b[2]; } dbl_byte; 138 union { double d; unsigned long int b[2]; } dbl_byte;
139 unsigned long int valbits = (rk & 0xfffffffc); 139 unsigned long int valbits = (rk & 0xfffffffc);
140#if defined(__arm__) && !defined(__vfp__) 140#if defined(__arm__) && !defined(__vfp__)
141 dbl_byte.b[0]=valbits; 141 dbl_byte.b[0]=valbits;
142 dbl_byte.b[1]=0; 142 dbl_byte.b[1]=0;
143#else 143#else
144 dbl_byte.b[0]=0; 144 dbl_byte.b[0]=0;
145 dbl_byte.b[1]=valbits; 145 dbl_byte.b[1]=valbits;
146#endif 146#endif
147 printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]); 147 printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]);
148 value=dbl_byte.d; 148 value=dbl_byte.d;
149 printf("Double4Byte: VALUE=%f\r\n",value); 149 printf("Double4Byte: VALUE=%f\r\n",value);
150 150
151 if ( (rk & 0x01) != 0) 151 if ( (rk & 0x01) != 0)
152 { 152 {
153 value /= 100.0; 153 value /= 100.0;
154 }; 154 };
155 return value; 155 return value;
156 }; 156 };
157}; 157};
158 158
159void ExcelBook::DetectEndian(void) 159void ExcelBook::DetectEndian(void)
160{ 160{
161 int end; 161 int end;
162 long i = 0x44332211; 162 long i = 0x44332211;
163 unsigned char* a = (unsigned char*) &i; 163 unsigned char* a = (unsigned char*) &i;
164 end = (*a != 0x11); 164 end = (*a != 0x11);
165 if (end == 1) 165 if (end == 1)
166 { 166 {
167 endian = BIG_ENDIAN; 167 endian = BIG_ENDIAN;
168 printf("BIGENDIAN!\r\n"); 168 printf("BIGENDIAN!\r\n");
169 } 169 }
170 else 170 else
171 { 171 {
172 endian = LITTLE_ENDIAN; 172 endian = LITTLE_ENDIAN;
173 printf("LITTLEENDIAN!\r\n"); 173 printf("LITTLEENDIAN!\r\n");
174 } 174 }
175}; 175};
176 176
177double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) 177double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8)
178{ 178{
179 int i; 179 int i;
180 double d; 180 double d;
181 unsigned char *ieee; 181 unsigned char *ieee;
182 ieee = (unsigned char *)&d; 182 ieee = (unsigned char *)&d;
183 for (i = 0; i < 8; i++) ieee[i] = 0; 183 for (i = 0; i < 8; i++) ieee[i] = 0;
184 if (endian == BIG_ENDIAN) 184 if (endian == BIG_ENDIAN)
185 { 185 {
186 ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff; 186 ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff;
187 ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff; 187 ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff;
188 ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff; 188 ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff;
189 ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff; 189 ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff;
190 } 190 }
191 else 191 else
192 { 192 {
193 ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff; 193 ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff;
194 ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff; 194 ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff;
195 ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff; 195 ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff;
196 ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff; 196 ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff;
197 } 197 }
198 return d; 198 return d;
199}; 199};
200 200
201bool ExcelBook::OpenFile(char *Filename) 201bool ExcelBook::OpenFile(char *Filename)
202{ 202{
203 printf("Opening excel file!\r\n"); 203 printf("Opening excel file!\r\n");
204 File= fopen(Filename, "r"); 204 File= fopen(Filename, "r");
205 Position=0; // first byte index in file 205 Position=0; // first byte index in file
206 XFRecords.resize(0); 206 XFRecords.resize(0);
207 SharedStrings.resize(0); 207 SharedStrings.resize(0);
208 Names.resize(0); 208 Names.resize(0);
209 Sheets.resize(0); 209 Sheets.resize(0);
210 if(File==NULL) return false; 210 if(File==NULL) return false;
211 printf("Opened excel file!\r\n"); 211 printf("Opened excel file!\r\n");
212 return true; 212 return true;
213}; 213};
214 214
215bool ExcelBook::CloseFile(void) 215bool ExcelBook::CloseFile(void)
216{ 216{
217 int w1; 217 int w1;
218 for(w1=0;w1<(int)XFRecords.count();w1++) 218 for(w1=0;w1<(int)XFRecords.count();w1++)
219 { 219 {
220 if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;}; 220 if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;};
221 }; 221 };
222 for(w1=0;w1<(int)SharedStrings.count();w1++) 222 for(w1=0;w1<(int)SharedStrings.count();w1++)
223 { 223 {
224 if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;}; 224 if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;};
225 }; 225 };
226 for(w1=0;w1<(int)Names.count();w1++) 226 for(w1=0;w1<(int)Names.count();w1++)
227 { 227 {
228 if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;}; 228 if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;};
229 }; 229 };
230 for(w1=0;w1<(int)Sheets.count();w1++) 230 for(w1=0;w1<(int)Sheets.count();w1++)
231 { 231 {
232 if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;}; 232 if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;};
233 }; 233 };
234 XFRecords.resize(0); 234 XFRecords.resize(0);
235 SharedStrings.resize(0); 235 SharedStrings.resize(0);
236 Names.resize(0); 236 Names.resize(0);
237 Sheets.resize(0); 237 Sheets.resize(0);
238 fclose(File); 238 fclose(File);
239 printf("closed excel file!\r\n"); 239 printf("closed excel file!\r\n");
240 if(File==NULL) return true; 240 if(File==NULL) return true;
241 return false; 241 return false;
242}; 242};
243 243
244void ExcelBook::SeekPosition(int pos) 244void ExcelBook::SeekPosition(int pos)
245{ 245{
246 if(!feof(File)) 246 if(!feof(File))
247 { 247 {
248 Position=pos; 248 Position=pos;
249 //printf("SeekPosition:Pos:%d\r\n",Position); 249 //printf("SeekPosition:Pos:%d\r\n",Position);
250 fseek(File,pos,SEEK_SET); 250 fseek(File,pos,SEEK_SET);
251 }; 251 };
252}; 252};
253 253
254void ExcelBook::SeekSkip(int pos) 254void ExcelBook::SeekSkip(int pos)
255{ 255{
256 if(!feof(File)) 256 if(!feof(File))
257 { 257 {
258 Position=Position+pos; 258 Position=Position+pos;
259 //printf("SeekSkip:Pos:%d\r\n",Position); 259 //printf("SeekSkip:Pos:%d\r\n",Position);
260 fseek(File, Position, SEEK_SET); 260 fseek(File, Position, SEEK_SET);
261 }; 261 };
262}; 262};
263 263
264int ExcelBook::FileEOF(void) 264int ExcelBook::FileEOF(void)
265{ 265{
266 if(File!=NULL) return(feof(File)); else return 0; 266 if(File!=NULL) return(feof(File)); else return 0;
267 //EOF is defined in stdlib as -1 267 //EOF is defined in stdlib as -1
268}; 268};
269 269
270int ExcelBook::Get2Bytes(void) 270int ExcelBook::Get2Bytes(void)
271{ 271{
272 int i1,i2; 272 int i1,i2;
273 i1=0; i2=0; 273 i1=0; i2=0;
274 if (!feof(File)) 274 if (!feof(File))
275 { 275 {
276 i1=fgetc(File); 276 i1=fgetc(File);
277 Position++; 277 Position++;
278 }; 278 };
279 if (!feof(File)) 279 if (!feof(File))
280 { 280 {
281 i2=fgetc(File); 281 i2=fgetc(File);
282 Position++; 282 Position++;
283 }; 283 };
284 return Integer2Byte(i1,i2); 284 return Integer2Byte(i1,i2);
285}; 285};
286 286
287char* ExcelBook::Read(int pos, int length) 287char* ExcelBook::Read(int pos, int length)
288{ 288{
289 int i; 289 int i;
290 char *data; 290 char *data;
291 data= new char[length]; 291 data= new char[length];
292 SeekPosition(pos); 292 SeekPosition(pos);
293 for(i=0; i<length; i++) 293 for(i=0; i<length; i++)
294 { 294 {
295 if(!feof(File)) data[i]=fgetc(File); 295 if(!feof(File)) data[i]=fgetc(File);
296 }; 296 };
297 Position= Position+length; 297 Position= Position+length;
298 return data; 298 return data;
299}; 299};
300 300
301QString ExcelBook::ReadUnicodeChar(int pos, int length) 301QString ExcelBook::ReadUnicodeChar(int pos, int length)
302{ 302{
303 int i; 303 int i;
304 QString data; 304 QString data;
305 int i1=' ',i2=' ',ii; 305 int i1=' ',i2=' ',ii;
306 SeekPosition(pos); 306 SeekPosition(pos);
307 for(i=0; i<length; i++) 307 for(i=0; i<length; i++)
308 { 308 {
309 if(!feof(File)) i1=fgetc(File); 309 if(!feof(File)) i1=fgetc(File);
310 if(!feof(File)) i2=fgetc(File); 310 if(!feof(File)) i2=fgetc(File);
311 ii=Integer2Byte(i1,i2); 311 ii=Integer2Byte(i1,i2);
312 data.append(ii); 312 data.append(ii);
313 Position+=2; 313 Position+=2;
314 }; 314 };
315 return data; 315 return data;
316}; 316};
317 317
318QString* ExcelBook::GetString(int num) 318QString* ExcelBook::GetString(int num)
319{ 319{
320 if(num>=0 && num<(int)SharedStrings.count()) 320 if(num>=0 && num<(int)SharedStrings.count())
321 { 321 {
322 return SharedStrings[num]; 322 return SharedStrings[num];
323 }; 323 };
324 return new QString(""); 324 return new QString("");
325}; 325};
326 326
327int ExcelBook::SeekBOF(void) 327int ExcelBook::SeekBOF(void)
328{ 328{
329 int opcode,version,streamtype,length,ret=0; 329 int opcode,version,streamtype,length,ret=0;
330 char *data; 330 char *data;
331 while(!feof(File)) 331 while(!feof(File))
332 { 332 {
333 opcode=Get2Bytes(); 333 opcode=Get2Bytes();
334 if(opcode==XL_BOF) 334 if(opcode==XL_BOF)
335 { 335 {
336 length=Get2Bytes(); 336 length=Get2Bytes();
337 data=Read(Position,length); 337 data=Read(Position,length);
338 version=Integer2Byte(data[0], data[1]); 338 version=Integer2Byte(data[0], data[1]);
339 streamtype=Integer2Byte(data[2], data[3]); 339 streamtype=Integer2Byte(data[2], data[3]);
340 printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version); 340 printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version);
341 delete [] data; data=NULL; 341 delete [] data; data=NULL;
342 if (version==BIFF8) ret=8; 342 if (version==BIFF8) ret=8;
343 else if(version==BIFF7) ret=7; 343 else if(version==BIFF7) ret=7;
344 printf("SEEKBOF:versionBIFF%d\r\n",ret); 344 printf("SEEKBOF:versionBIFF%d\r\n",ret);
345 if(streamtype==WBKGLOBAL) return ret *2; 345 if(streamtype==WBKGLOBAL) return ret *2;
346 else if(streamtype==WRKSHEET) return ret *1; 346 else if(streamtype==WRKSHEET) return ret *1;
347 return 1; 347 return 1;
348 }; 348 };
349 }; 349 };
350 return 0; 350 return 0;
351}; 351};
352 352
353ExcelBREC* ExcelBook::GetBREC(void) 353ExcelBREC* ExcelBook::GetBREC(void)
354{ 354{
355 ExcelBREC* rec; 355 ExcelBREC* rec;
356 rec= new ExcelBREC; 356 rec= new ExcelBREC;
357 if(FileEOF()) return NULL; 357 if(FileEOF()) return NULL;
358 rec->data=NULL; 358 rec->data=NULL;
359 rec->code=Get2Bytes(); 359 rec->code=Get2Bytes();
360 rec->length=Get2Bytes(); 360 rec->length=Get2Bytes();
361 rec->position=Position; 361 rec->position=Position;
362 SeekSkip(rec->length); 362 SeekSkip(rec->length);
363 return rec; 363 return rec;
364}; 364};
365 365
366ExcelBREC* ExcelBook::PeekBREC(void) 366ExcelBREC* ExcelBook::PeekBREC(void)
367{ 367{
368 int oldpos; 368 int oldpos;
369 ExcelBREC* NextRec; 369 ExcelBREC* NextRec;
370 oldpos=Position; 370 oldpos=Position;
371 NextRec=GetBREC(); 371 NextRec=GetBREC();
372 SeekPosition(oldpos); 372 SeekPosition(oldpos);
373 return NextRec; 373 return NextRec;
374}; 374};
375 375
376char* ExcelBook::GetDataOfBREC(ExcelBREC* record) 376char* ExcelBook::GetDataOfBREC(ExcelBREC* record)
377{ 377{
378 if(record->data==NULL) 378 if(record->data==NULL)
379 { 379 {
380 ConvertCharToArray(record,Read(record->position,record->length),record->length); 380 char* readData = Read(record->position,record->length);
381 ConvertCharToArray(record,readData,record->length);
382 delete [] readData;
381 }; 383 };
382 return record->data;//new? 384 return record->data;//new?
383}; 385};
384 386
385void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) 387void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length)
386{ 388{
387 record->data=new char[length]; 389 record->data=new char[length];
388 for(int w1=0;w1<=length-1;w1++) 390 for(int w1=0;w1<=length-1;w1++)
389 record->data[w1]=chars[w1]; 391 record->data[w1]=chars[w1];
390}; 392};
391 393
392 394
393bool ExcelSheet::InitCells() 395bool ExcelSheet::InitCells()
394{ 396{
395 int r; 397 int r;
396 Cells.resize(rows * cols + cols+1); 398 Cells.resize(rows * cols + cols+1);
397 if(Cells.count()==0) return false; 399 if(Cells.count()==0) return false;
398 for(r=0;r < Cells.count();r++) 400 for(r=0;r < Cells.count();r++)
399 { 401 {
400 Cells[r]=NULL; 402 Cells[r]=NULL;
401 }; 403 };
402 return true; 404 return true;
403}; 405};
404 406
405void ExcelSheet::Set(int row, int col, ExcelCell* cell) 407void ExcelSheet::Set(int row, int col, ExcelCell* cell)
406{ 408{
407 if(cell!=NULL&&(row*cols+col)<Cells.count()) 409 if(cell!=NULL&&(row*cols+col)<Cells.count())
408 { 410 {
409 Cells[row*cols+col]=cell; 411 Cells[row*cols+col]=cell;
410 }; 412 };
411}; 413};
412 414
413ExcelCell* ExcelSheet::Get(int row, int col) 415ExcelCell* ExcelSheet::Get(int row, int col)
414{ 416{
415 ExcelCell* cell; 417 ExcelCell* cell;
416 cell=Cells[row*cols+col]; 418 cell=Cells[row*cols+col];
417 if(cell==NULL) return NULL; 419 if(cell==NULL) return NULL;
418 return cell; 420 return cell;
419}; 421};
420 422
421int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) 423int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record)
422{ 424{
423 char* data=NULL; 425 char* data=NULL;
424 switch (record->code) 426 switch (record->code)
425 { 427 {
426 case XL_DIMENSION: 428 case XL_DIMENSION:
427 data = GetDataOfBREC(record); 429 data = GetDataOfBREC(record);
428 if (record->length == 10) 430 if (record->length == 10)
429 { 431 {
430 sheet->rows = Integer2Byte(data[2], data[3]); 432 sheet->rows = Integer2Byte(data[2], data[3]);
431 sheet->cols = Integer2Byte(data[6], data[7]); 433 sheet->cols = Integer2Byte(data[6], data[7]);
432 } 434 }
433 else 435 else
434 { 436 {
435 sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]); 437 sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]);
436 sheet->cols = Integer2Byte(data[10], data[11]); 438 sheet->cols = Integer2Byte(data[10], data[11]);
437 } 439 }
438 sheet->InitCells(); 440 sheet->InitCells();
439 break; 441 break;
440 442
441 case XL_LABELSST: 443 case XL_LABELSST:
442 HandleLabelSST(sheet, record); 444 HandleLabelSST(sheet, record);
443 break; 445 break;
444 446
445 case XL_RK: 447 case XL_RK:
446 case XL_RK2: 448 case XL_RK2:
447 HandleRK(sheet, record); 449 HandleRK(sheet, record);
448 break; 450 break;
449 451
450 case XL_MULRK: 452 case XL_MULRK:
451 HandleMulrk(sheet, record); 453 HandleMulrk(sheet, record);
452 break; 454 break;
453 455
454 case XL_ROW: 456 case XL_ROW:
455 break; 457 break;
456 458
457 case XL_NUMBER: 459 case XL_NUMBER:
458 HandleNumber(sheet, record); 460 HandleNumber(sheet, record);
459 break; 461 break;
460 462
461 case XL_BOOLERR: 463 case XL_BOOLERR:
462 break; 464 break;
463 465
464 case XL_CONTINUE: 466 case XL_CONTINUE:
465 break; 467 break;
466 468
467 case XL_FORMULA: 469 case XL_FORMULA:
468 case XL_FORMULA2: 470 case XL_FORMULA2:
469 HandleFormula(sheet, record); 471 HandleFormula(sheet, record);
470 break; 472 break;
471 473
472 case XL_LABEL: 474 case XL_LABEL:
473 break; 475 break;
474 476
475 case XL_NAME: 477 case XL_NAME:
476 HandleName(sheet, record); 478 HandleName(sheet, record);
477 break; 479 break;
478 480
479 case XL_BOF: 481 case XL_BOF:
480 break; 482 break;
481 case XL_EOF: 483 case XL_EOF:
482 return 0; 484 return 0;
483 default: 485 default:
484 break; 486 break;
485 }; 487 };
486 return 1; 488 return 1;
487}; 489};
488 490
489int ExcelBook::ReadSheet(ExcelSheet* sheet) 491int ExcelBook::ReadSheet(ExcelSheet* sheet)
490{ 492{
491 ExcelBREC* record; 493 ExcelBREC* record;
492 int oldpos; 494 int oldpos;
493 oldpos = Position; 495 oldpos = Position;
494 SeekPosition(sheet->position); 496 SeekPosition(sheet->position);
495 record = GetBREC(); 497 record = GetBREC();
496 while (record!=NULL) 498 while (record!=NULL)
497 { 499 {
498 if (!SheetHandleRecord(sheet, record)) break; 500 if (!SheetHandleRecord(sheet, record)) break;
499 record=GetBREC(); 501 record=GetBREC();
500 }; 502 };
501 SeekPosition(oldpos); 503 SeekPosition(oldpos);
502 return 1; 504 return 1;
503}; 505};
504 506
505ExcelSheet* ExcelBook::GetSheet(void) 507ExcelSheet* ExcelBook::GetSheet(void)
506{ 508{
507 ExcelSheet* sh=NULL; 509 ExcelSheet* sh=NULL;
508 int type; 510 int type;
509 type=SeekBOF(); 511 type=SeekBOF();
510 Version=type; 512 Version=type;
511 sh=new ExcelSheet; 513 sh=new ExcelSheet;
512 if(type) 514 if(type)
513 { 515 {
514 sh->type=type; 516 sh->type=type;
515 sh->position=Position; 517 sh->position=Position;
516 sh->name=QString(""); 518 sh->name=QString("");
517 }; 519 };
518 if(type==8||type==7) 520 if(type==8||type==7)
519 { 521 {
520 ReadSheet(sh); 522 ReadSheet(sh);
521 }; 523 };
522 return sh; 524 return sh;
523}; 525};
524 526
525void ExcelBook::ParseSheets(void) 527void ExcelBook::ParseSheets(void)
526{ 528{
527 int BOFs; 529 int BOFs;
528 ExcelBREC* r; 530 ExcelBREC* r;
529 BOFs=1; 531 BOFs=1;
530 r=GetBREC(); 532 r=GetBREC();
531 while(BOFs) 533 while(BOFs)
532 { 534 {
533 r=GetBREC(); 535 r=GetBREC();
534 switch(r->code) 536 switch(r->code)
535 { 537 {
536 case XL_SST: 538 case XL_SST:
537 HandleSST(r); 539 HandleSST(r);
538 break; 540 break;
539 541
540 case XL_TXO: 542 case XL_TXO:
541 break; 543 break;
542 case XL_NAME: 544 case XL_NAME:
543 break; 545 break;
544 case XL_ROW: 546 case XL_ROW:
545 break; 547 break;
546 548
547 case XL_FORMAT: 549 case XL_FORMAT:
548 HandleFormat(r); 550 HandleFormat(r);
549 break; 551 break;
550 552
551 case XL_XF: 553 case XL_XF:
552 HandleXF(r); 554 HandleXF(r);
553 break; 555 break;
554 556
555 case XL_BOUNDSHEET: 557 case XL_BOUNDSHEET:
556 HandleBoundSheet(r); 558 HandleBoundSheet(r);
557 break; 559 break;
558 560
559 case XL_EXTSST: 561 case XL_EXTSST:
560 break; 562 break;
561 case XL_CONTINUE: 563 case XL_CONTINUE:
562 break; 564 break;
563 565
564 case XL_EOF: 566 case XL_EOF:
565 BOFs--; 567 BOFs--;
566 break; 568 break;
567 569
568 default: 570 default:
569 break; 571 break;
570 }; 572 };
571 }; 573 };
572}; 574};
573 575
574void ExcelBook::GetSheets(void) 576void ExcelBook::GetSheets(void)
575{ 577{
576 ExcelSheet* sheet; 578 ExcelSheet* sheet;
577 Sheets.resize(0); 579 Sheets.resize(0);
578 sheet=GetSheet(); 580 sheet=GetSheet();
579 while (sheet->Cells.count()!= 0 ) 581 while (sheet->Cells.count()!= 0 )
580 { 582 {
581 Sheets.resize(Sheets.count()+1); 583 Sheets.resize(Sheets.count()+1);
582 Sheets[Sheets.count()-1]=sheet; 584 Sheets[Sheets.count()-1]=sheet;
583 sheet->name=*Names[Sheets.count()-1]; 585 sheet->name=*Names[Sheets.count()-1];
584 sheet=GetSheet(); 586 sheet=GetSheet();
585 }; 587 };
586}; 588};
587 589
588bool ExcelBook::ParseBook(char *file) 590bool ExcelBook::ParseBook(char *file)
589{ 591{
590 dateformat=QString(""); 592 dateformat=QString("");
591 DetectEndian(); 593 DetectEndian();
592 if ( !OpenFile( file ) ) 594 if ( !OpenFile( file ) )
593 return false; 595 return false;
594 SeekBOF(); 596 SeekBOF();
595 ParseSheets(); 597 ParseSheets();
596 GetSheets(); 598 GetSheets();
597 return true; 599 return true;
598}; 600};
599 601
600QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) 602QString ExcelBook::GetASCII(char* inbytes, int pos, int chars)
601{ 603{
602 int i; 604 int i;
603 QString outstr=""; 605 QString outstr="";
604 for (i = 0; i < chars; i++) 606 for (i = 0; i < chars; i++)
605 { 607 {
606 outstr.append(inbytes[i+pos]); 608 outstr.append(inbytes[i+pos]);
607 }; 609 };
608 return outstr; 610 return outstr;
609}; 611};
610 612
611QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) 613QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars)
612{ 614{
613 QString outstr=""; 615 QString outstr="";
614 int i; 616 int i;
615 int rc; 617 int rc;
616 for (i=0; i<chars*2; i++) 618 for (i=0; i<chars*2; i++)
617 { 619 {
618 rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]); 620 rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]);
619 outstr.append(QChar(rc)); 621 outstr.append(QChar(rc));
620 i++; 622 i++;
621 }; 623 };
622 return outstr; 624 return outstr;
623}; 625};
624 626
625 627
626void ExcelBook::HandleBoundSheet(ExcelBREC* rec) 628void ExcelBook::HandleBoundSheet(ExcelBREC* rec)
627{ 629{
628 char* data; 630 char* data;
629 int type; 631 int type;
630 int visibility; 632 int visibility;
631 int length; 633 int length;
632 int pos; 634 int pos;
633 QString name; 635 QString name;
634 pos = 8; 636 pos = 8;
635 data = GetDataOfBREC(rec); 637 data = GetDataOfBREC(rec);
636 type = data[4]; 638 type = data[4];
637 visibility = data[5]; 639 visibility = data[5];
638 length = data[6]; 640 length = data[6];
639 if(data[7]==0) 641 if(data[7]==0)
640 { 642 {
641 //ascii 643 //ascii
642 name=GetASCII(data,pos,length); 644 name=GetASCII(data,pos,length);
643 } 645 }
644 else 646 else
645 { 647 {
646 name=GetUnicode(data,pos,length); 648 name=GetUnicode(data,pos,length);
647 }; 649 };
648 Names.resize(Names.count()+1); 650 Names.resize(Names.count()+1);
649 Names[Names.count()-1]=new QString(name); 651 Names[Names.count()-1]=new QString(name);
650}; 652};
651 653
652void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) 654void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec)
653{ 655{
654 char* data; 656 char* data;
655 QString name; 657 QString name;
656 int length; 658 int length;
657 int pos; 659 int pos;
658 pos = 15; 660 pos = 15;
659 data = GetDataOfBREC(rec); 661 data = GetDataOfBREC(rec);
660 length = data[3]; 662 length = data[3];
661 name = GetASCII(data,pos,length); 663 name = GetASCII(data,pos,length);
662 664
663 665
664}; 666};
665 667
666ExcelFormat* ExcelBook::GetFormatting(int xf) 668ExcelFormat* ExcelBook::GetFormatting(int xf)
667{ 669{
668 int i; 670 int i;
669 ExcelFormat* rec; 671 ExcelFormat* rec;
670 rec=new ExcelFormat(); 672 rec=new ExcelFormat();
671 for (i = 0; formatter[i].code != 0; i++) 673 for (i = 0; formatter[i].code != 0; i++)
672 { 674 {
673 if (xf == formatter[i].code) break; 675 if (xf == formatter[i].code) break;
674 }; 676 };
675 if (formatter[i].format ==NULL) return NULL; 677 if (formatter[i].format ==NULL) return NULL;
676 rec->code = xf; 678 rec->code = xf;
677 rec->type = formatter[i].type; 679 rec->type = formatter[i].type;
678 rec->format = formatter[i].format; 680 rec->format = formatter[i].format;
679 return rec; 681 return rec;
680}; 682};
681 683
682void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) 684void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes)
683{ 685{
684 QString str=QString(""); 686 QString str=QString("");
685 char* data; 687 char* data;
686 int chars, pos, options, i; 688 int chars, pos, options, i;
687 int richstring, fareaststring, runlength=0; 689 int richstring, fareaststring, runlength=0;
688 int richruns=0,fareastsize=0; 690 int richruns=0,fareastsize=0;
689 int totalstrings; 691 int totalstrings;
690 int uniquestrings; 692 int uniquestrings;
691 data = GetDataOfBREC(rec); 693 data = GetDataOfBREC(rec);
692 totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]); 694 totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]);
693 uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]); 695 uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]);
694 pos = 8; 696 pos = 8;
695 for (i = 0; i < uniquestrings; i++) 697 for (i = 0; i < uniquestrings; i++)
696 { 698 {
697 richruns=0; fareastsize=0; 699 richruns=0; fareastsize=0;
698 chars = Integer2Byte(data[pos], data[pos+1]); 700 chars = Integer2Byte(data[pos], data[pos+1]);
699 pos += 2; 701 pos += 2;
700 options = data[pos]; 702 options = data[pos];
701 pos++; 703 pos++;
702 fareaststring = ((options & 0x04) != 0); 704 fareaststring = ((options & 0x04) != 0);
703 richstring = ((options & 0x08) != 0); 705 richstring = ((options & 0x08) != 0);
704 if(richstring) 706 if(richstring)
705 { 707 {
706 richruns= Integer2Byte(data[pos],data[pos+1]); 708 richruns= Integer2Byte(data[pos],data[pos+1]);
707 pos+=2; 709 pos+=2;
708 }; 710 };
709 if(fareaststring) 711 if(fareaststring)
710 { 712 {
711 fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]); 713 fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]);
712 pos+=4; 714 pos+=4;
713 }; 715 };
714 716
715 if ((options & 0x01) == 0) //8 bit chars 717 if ((options & 0x01) == 0) //8 bit chars
716 { 718 {
717 /* ascii */ 719 /* ascii */
718 str = GetASCII(bytes,pos,chars); 720 str = GetASCII(bytes,pos,chars);
719 pos=pos+chars; 721 pos=pos+chars;
720 if(str[0]=='=') str[0]=' '; 722 if(str[0]=='=') str[0]=' ';
721 }else //16 bit chars 723 }else //16 bit chars
722 { 724 {
723 /* unicode */ 725 /* unicode */
724 str = GetUnicode(bytes,pos,chars); 726 str = GetUnicode(bytes,pos,chars);
725 pos=pos+chars*2; 727 pos=pos+chars*2;
726 }; 728 };
727 // HERE TO PUT richformat handling 729 // HERE TO PUT richformat handling
728 if (richstring) 730 if (richstring)
729 { 731 {
730 pos += 4 * richruns; 732 pos += 4 * richruns;
731 }; 733 };
732 if (fareaststring) 734 if (fareaststring)
733 { 735 {
734 pos += fareastsize; 736 pos += fareastsize;
735 }; 737 };
736 //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode()); 738 //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode());
737 SharedStrings.resize(SharedStrings.count()+1); 739 SharedStrings.resize(SharedStrings.count()+1);
738 SharedStrings[SharedStrings.count()-1]=new QString(str); 740 SharedStrings[SharedStrings.count()-1]=new QString(str);
739 } 741 }
740}; 742};
741 743
742 744
743char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) 745char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont)
744{ 746{
745 int i, pos; 747 int i, pos;
746 int length; 748 int length;
747 749
748 char* data; 750 char* data;
749 char* bytes; 751 char* bytes;
750 length = rec->length; 752 length = rec->length;
751 for (i = 0; i < (int) cont->rec.count(); i++) 753 for (i = 0; i < (int) cont->rec.count(); i++)
752 { 754 {
753 length += cont->rec[i]->length; 755 length += cont->rec[i]->length;
754 } 756 }
755 bytes = GetDataOfBREC(rec); 757 bytes = GetDataOfBREC(rec);
756 pos = rec->length; 758 pos = rec->length;
757 for (i = 0; i < (int) cont->rec.count(); i++) 759 for (i = 0; i < (int) cont->rec.count(); i++)
758 { 760 {
759 data = GetDataOfBREC(cont->rec[i]); 761 data = GetDataOfBREC(cont->rec[i]);
760 *bytes += pos; 762 *bytes += pos;
761 bytes = data; 763 bytes = data;
762 pos += cont->rec[i]->length; 764 pos += cont->rec[i]->length;
763 } 765 }
764 return bytes; 766 return bytes;
765}; 767};
766 768
767 769
768void ExcelBook::HandleSST(ExcelBREC* rec) 770void ExcelBook::HandleSST(ExcelBREC* rec)
769{ 771{
770 char* bytes; 772 char* bytes;
771 SSTList* cont; 773 SSTList* cont;
772 cont= new SSTList; 774 cont= new SSTList;
773 ExcelBREC* nr; 775 ExcelBREC* nr;
774 nr = PeekBREC(); 776 nr = PeekBREC();
775 while (nr->code == XL_CONTINUE) 777 while (nr->code == XL_CONTINUE)
776 { 778 {
777 cont->rec.resize(cont->rec.count()+1); 779 cont->rec.resize(cont->rec.count()+1);
778 cont->rec[cont->rec.count()-1]=GetBREC(); 780 cont->rec[cont->rec.count()-1]=GetBREC();
779 nr = PeekBREC(); 781 nr = PeekBREC();
780 } 782 }
781 bytes = MergeBytesFromSSTs(rec,cont); 783 bytes = MergeBytesFromSSTs(rec,cont);
782 HandleSetOfSST(rec, bytes); 784 HandleSetOfSST(rec, bytes);
783 for(int w1=0;w1<(int)cont->rec.count();w1++) 785 for(int w1=0;w1<(int)cont->rec.count();w1++)
784 { 786 {
785 if(cont->rec[w1]!=NULL) {delete cont->rec[w1];cont->rec[w1]=NULL;}; 787 if(cont->rec[w1]!=NULL) {delete cont->rec[w1];cont->rec[w1]=NULL;};
786 }; 788 };
787 cont->rec.resize(0); 789 cont->rec.resize(0);
788}; 790};
789 791
790void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec) 792void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec)
791{ 793{
792 int index, row, col; 794 int index, row, col;
793 char* data; 795 char* data;
794 data = GetDataOfBREC(rec); 796 data = GetDataOfBREC(rec);
795 index = Integer4Byte(data[6], data[7], data[8], data[9]); 797 index = Integer4Byte(data[6], data[7], data[8], data[9]);
796 row = Integer2Byte(data[0], data[1]); 798 row = Integer2Byte(data[0], data[1]);
797 col = Integer2Byte(data[2], data[3]); 799 col = Integer2Byte(data[2], data[3]);
798 sheet->Set(row,col, CellLabel(row, col, *GetString(index))); 800 sheet->Set(row,col, CellLabel(row, col, *GetString(index)));
799}; 801};
800 802
801ExcelCell* ExcelBook::CellLabel(int row, int col, QString str) 803ExcelCell* ExcelBook::CellLabel(int row, int col, QString str)
802{ 804{
803 ExcelCell* c; 805 ExcelCell* c;
804 c= new ExcelCell; 806 c= new ExcelCell;
805 c->row = row; 807 c->row = row;
806 c->col = col; 808 c->col = col;
807 c->type = CELL_LABEL; 809 c->type = CELL_LABEL;
808 c->valuec = str; 810 c->valuec = str;
809 return c; 811 return c;
810}; 812};
811 813
812ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d) 814ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d)
813{ 815{
814 ExcelCell* c; 816 ExcelCell* c;
815 c=new ExcelCell; 817 c=new ExcelCell;
816 c->row = row; 818 c->row = row;
817 c->col = col; 819 c->col = col;
818 c->xfindex = index; 820 c->xfindex = index;
819 c->type = CELL_NUMBER; 821 c->type = CELL_NUMBER;
820 c->valued = d; 822 c->valued = d;
821 return c; 823 return c;
822}; 824};
823 825
824QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col) 826QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col)
825{ 827{
826 time_t date; 828 time_t date;
827 struct tm *tmptr; 829 struct tm *tmptr;
828 ExcelCell* c; 830 ExcelCell* c;
829 char str[128]; 831 char str[128];
830 QString format; 832 QString format;
831 int precision; 833 int precision;
832 int utcOffsetDays = 25569; 834 int utcOffsetDays = 25569;
833 int sInADay = 24 * 60 * 60; 835 int sInADay = 24 * 60 * 60;
834 c = sh->Get(row,col); 836 c = sh->Get(row,col);
835 if (c == NULL) return new QString(""); 837 if (c == NULL) return new QString("");
836 switch (c->type) 838 switch (c->type)
837 { 839 {
838 case CELL_LABEL: 840 case CELL_LABEL:
839 return new QString(c->valuec); 841 return new QString(c->valuec);
840 case CELL_NUMBER: 842 case CELL_NUMBER:
841 if (XFRecords[c->xfindex]->type == DATEFORMAT) 843 if (XFRecords[c->xfindex]->type == DATEFORMAT)
842 { 844 {
843 845
844 format = XFRecords[c->xfindex]->format; 846 format = XFRecords[c->xfindex]->format;
845 date = (time_t) ((c->valued - utcOffsetDays) * sInADay); 847 date = (time_t) ((c->valued - utcOffsetDays) * sInADay);
846 tmptr = gmtime(&date); 848 tmptr = gmtime(&date);
847 if (dateformat) 849 if (dateformat)
848 { 850 {
849 strftime(str,1024,dateformat.ascii(),tmptr); 851 strftime(str,1024,dateformat.ascii(),tmptr);
850 } 852 }
851 else 853 else
852 { 854 {
853 strftime(str,1024,format.ascii(),tmptr); 855 strftime(str,1024,format.ascii(),tmptr);
854 }; 856 };
855 } 857 }
856 else 858 else
857 if (XFRecords[c->xfindex]->type == NUMBERFORMAT) 859 if (XFRecords[c->xfindex]->type == NUMBERFORMAT)
858 { 860 {
859 format = XFRecords[c->xfindex]->format; 861 format = XFRecords[c->xfindex]->format;
860 //sprintf(str,format.ascii(),c->valued); 862 //sprintf(str,format.ascii(),c->valued);
861 // the real format is ignored... 863 // the real format is ignored...
862 // because there is more work to be done in the field 864 // because there is more work to be done in the field
863 precision = CellGetPrecision(c->valued); 865 precision = CellGetPrecision(c->valued);
864 sprintf(str,"%.*f",precision,c->valued); 866 sprintf(str,"%.*f",precision,c->valued);
865 } 867 }
866 else 868 else
867 { 869 {
868 precision = CellGetPrecision(c->valued); 870 precision = CellGetPrecision(c->valued);
869 sprintf(str,"%.*f",precision,c->valued); 871 sprintf(str,"%.*f",precision,c->valued);
870 }; 872 };
871 break; 873 break;
872 case CELL_DATE: 874 case CELL_DATE:
873 break; 875 break;
874 case CELL_BOOLEAN: 876 case CELL_BOOLEAN:
875 break; 877 break;
876 case CELL_ERROR: 878 case CELL_ERROR:
877 break; 879 break;
878 } 880 }
879 return new QString(str); 881 return new QString(str);
880}; 882};
881 883
882int ExcelBook::CellGetPrecision(double d) 884int ExcelBook::CellGetPrecision(double d)
883{ 885{
884 double t; 886 double t;
885 int i,x; 887 int i,x;
886 int count; 888 int count;
887 if (d < 0) d *= -1; 889 if (d < 0) d *= -1;
888 i = (int)d; 890 i = (int)d;
889 t = d - (double)i; 891 t = d - (double)i;
890 if (t <= 0) 892 if (t <= 0)
891 { 893 {
892 return 0; 894 return 0;
893 }; 895 };
894 count = 0; 896 count = 0;
895 for (x = 6; x > 1; x--) 897 for (x = 6; x > 1; x--)
896 { 898 {
897 i = (int)d; 899 i = (int)d;
898 t = d - (double)i; 900 t = d - (double)i;
899 t *= pow(10,x - 2); 901 t *= pow(10,x - 2);
900 i = (int)t; 902 i = (int)t;
901 t = t - (double)i; 903 t = t - (double)i;
902 t *= 10; 904 t *= 10;
903 i = (int)t; 905 i = (int)t;
904 if (i > 0) break; 906 if (i > 0) break;
905 count++; 907 count++;
906 }; 908 };
907 return (5 - count); 909 return (5 - count);
908}; 910};
909 911
910 912
911void ExcelBook::CellSetDateFormat(char *d) 913void ExcelBook::CellSetDateFormat(char *d)
912{ 914{
913 dateformat = QString(d); 915 dateformat = QString(d);
914}; 916};
915 917
916void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record) 918void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record)
917{ 919{
918 struct mulrk mulrk; 920 struct mulrk mulrk;
919 char* data; 921 char* data;
920 ExcelCell* cell; 922 ExcelCell* cell;
921 int len; 923 int len;
922 int i; 924 int i;
923 len = record->length; 925 len = record->length;
924 data = GetDataOfBREC(record); 926 data = GetDataOfBREC(record);
925 mulrk.row = Integer2Byte(data[0],data[1]); 927 mulrk.row = Integer2Byte(data[0],data[1]);
926 mulrk.first = Integer2Byte(data[2],data[3]); 928 mulrk.first = Integer2Byte(data[2],data[3]);
927 mulrk.last = Integer2Byte(data[len - 2],data[len - 1]); 929 mulrk.last = Integer2Byte(data[len - 2],data[len - 1]);
928 mulrk.numrks = mulrk.last - mulrk.first + 1; 930 mulrk.numrks = mulrk.last - mulrk.first + 1;
929 MulrkRead(&mulrk, data); 931 MulrkRead(&mulrk, data);
930 for (i = 0; i < mulrk.numrks; i++) 932 for (i = 0; i < mulrk.numrks; i++)
931 { 933 {
932 cell = CellNumber(mulrk.row, mulrk.first + i, mulrk.xfindices[i], mulrk.rkdbls[i]); 934 cell = CellNumber(mulrk.row, mulrk.first + i, mulrk.xfindices[i], mulrk.rkdbls[i]);
933 sheet->Set(mulrk.row,mulrk.first+ i, cell); 935 sheet->Set(mulrk.row,mulrk.first+ i, cell);
934 //printf("handleMULRK:row=%d,col=%d,val=%f\r\n",mulrk.row,mulrk.first+i,mulrk.rkdbls[i]); 936 //printf("handleMULRK:row=%d,col=%d,val=%f\r\n",mulrk.row,mulrk.first+i,mulrk.rkdbls[i]);
935 } 937 }
936 //delete(mulrk.xfindices); 938 //delete(mulrk.xfindices);
937 //delete(mulrk.rkdbls); 939 //delete(mulrk.rkdbls);
938}; 940};
939 941
940void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data) 942void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data)
941{ 943{
942 double d; 944 double d;
943 int i; 945 int i;
944 int pos; 946 int pos;
945 pos = 4; 947 pos = 4;
946 mulrk->xfindices.resize(mulrk->numrks); 948 mulrk->xfindices.resize(mulrk->numrks);
947 mulrk->rkdbls.resize(mulrk->numrks); 949 mulrk->rkdbls.resize(mulrk->numrks);
948 for (i = 0; i < mulrk->numrks; i++) 950 for (i = 0; i < mulrk->numrks; i++)
949 { 951 {
950 mulrk->xfindices[i] = Integer2Byte(data[pos], data[pos+1]); 952 mulrk->xfindices[i] = Integer2Byte(data[pos], data[pos+1]);
951 d=Double4Byte(data[pos+2], data[pos+3], data[pos+4], data[pos+5]); 953 d=Double4Byte(data[pos+2], data[pos+3], data[pos+4], data[pos+5]);
952 //printf("double:%f\r\n",d); 954 //printf("double:%f\r\n",d);
953 mulrk->rkdbls[i] = d; 955 mulrk->rkdbls[i] = d;
954 pos += 6; 956 pos += 6;
955 } 957 }
956}; 958};
957 959
958 960
959void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record) 961void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record)
960{ 962{
961 int xfindex, row, col; 963 int xfindex, row, col;
962 char* data; 964 char* data;
963 double d; 965 double d;
964 data = GetDataOfBREC(record); 966 data = GetDataOfBREC(record);
965 row = Integer2Byte(data[0], data[1]); 967 row = Integer2Byte(data[0], data[1]);
966 col = Integer2Byte(data[2], data[3]); 968 col = Integer2Byte(data[2], data[3]);
967 xfindex = Integer2Byte(data[4], data[5]); 969 xfindex = Integer2Byte(data[4], data[5]);
968#if defined(__arm__) && !defined(__vfp__) 970#if defined(__arm__) && !defined(__vfp__)
969 d=Double8Byte(data[10], data[11], data[12], data[13],data[6], data[7], data[8], data[9]); 971 d=Double8Byte(data[10], data[11], data[12], data[13],data[6], data[7], data[8], data[9]);
970#else 972#else
971 d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]); 973 d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
972#endif 974#endif
973 //even if ARM is little endian... doubles are been placed as bigendian words. 975 //even if ARM is little endian... doubles are been placed as bigendian words.
974 //thanks pb_ for that. :) 976 //thanks pb_ for that. :)
975 sheet->Set(row,col, CellNumber(row,col,xfindex,d)); 977 sheet->Set(row,col, CellNumber(row,col,xfindex,d));
976 //printf("handleNumber:row=%d,col=%d,val=%f\r\n",row,col,d); 978 //printf("handleNumber:row=%d,col=%d,val=%f\r\n",row,col,d);
977}; 979};
978 980
979ExcelFormat::ExcelFormat() 981ExcelFormat::ExcelFormat()
980{ 982{
981 code=0;type=0;format=""; 983 code=0;type=0;format="";
982}; 984};
983 985
984ExcelFormat::ExcelFormat(int c,int t, QString s) 986ExcelFormat::ExcelFormat(int c,int t, QString s)
985{ 987{
986 code=c;type=t;format=s; 988 code=c;type=t;format=s;
987}; 989};
988 990
989 991
990void ExcelBook::HandleFormat(ExcelBREC* rec) 992void ExcelBook::HandleFormat(ExcelBREC* rec)
991{ 993{
992 ExcelFormat* xfrec; 994 ExcelFormat* xfrec;
993 char* data; 995 char* data;
994 int format; 996 int format;
995 data = GetDataOfBREC(rec); 997 data = GetDataOfBREC(rec);
996 format = Integer2Byte(data[2],data[3]); 998 format = Integer2Byte(data[2],data[3]);
997 xfrec = GetFormatting(format); 999 xfrec = GetFormatting(format);
998 /*int idx; 1000 /*int idx;
999 idx=XFRecords.count()-1; 1001 idx=XFRecords.count()-1;
1000 XFRecords[idx]->code=xfrec->code; 1002 XFRecords[idx]->code=xfrec->code;
1001 XFRecords[idx]->type=xfrec->type; 1003 XFRecords[idx]->type=xfrec->type;
1002 XFRecords[idx]->format="manos"; 1004 XFRecords[idx]->format="manos";
1003 //XFRecords[XFRecords.count()-1]=xfrec; 1005 //XFRecords[XFRecords.count()-1]=xfrec;
1004 printf("6\r\n");*/ 1006 printf("6\r\n");*/
1005}; 1007};
1006 1008
1007void ExcelBook::HandleXF(ExcelBREC* rec) 1009void ExcelBook::HandleXF(ExcelBREC* rec)
1008{ 1010{
1009 ExcelFormat* xfrec; 1011 ExcelFormat* xfrec;
1010 char* data; 1012 char* data;
1011 int format; 1013 int format;
1012 data = GetDataOfBREC(rec); 1014 data = GetDataOfBREC(rec);
1013 format = Integer2Byte(data[2],data[3]); 1015 format = Integer2Byte(data[2],data[3]);
1014 xfrec = GetFormatting(format); 1016 xfrec = GetFormatting(format);
1015 XFRecords.resize(XFRecords.count()+1); 1017 XFRecords.resize(XFRecords.count()+1);
1016 XFRecords[XFRecords.count()-1]=xfrec; 1018 XFRecords[XFRecords.count()-1]=xfrec;
1017}; 1019};
1018 1020
1019 1021
1020 1022
1021void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record) 1023void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record)
1022{ 1024{
1023 int xfindex, row, col; 1025 int xfindex, row, col;
1024 char* data; 1026 char* data;
1025 double d; 1027 double d;
1026 data = GetDataOfBREC(record); 1028 data = GetDataOfBREC(record);
1027 row = Integer2Byte(data[0], data[1]); 1029 row = Integer2Byte(data[0], data[1]);
1028 col = Integer2Byte(data[2], data[3]); 1030 col = Integer2Byte(data[2], data[3]);
1029 xfindex = Integer2Byte(data[4], data[5]); 1031 xfindex = Integer2Byte(data[4], data[5]);
1030 d=Double4Byte(data[6], data[7], data[8], data[9]); 1032 d=Double4Byte(data[6], data[7], data[8], data[9]);
1031 sheet->Set(row,col,CellNumber(row,col,xfindex,d)); 1033 sheet->Set(row,col,CellNumber(row,col,xfindex,d));
1032 //printf("handleRK:row=%d,col=%d,val=%f\r\n",row,col,d); 1034 //printf("handleRK:row=%d,col=%d,val=%f\r\n",row,col,d);
1033}; 1035};
1034 1036
1035 1037
1036void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record) 1038void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record)
1037{ 1039{
1038 int xfindex, row, col; 1040 int xfindex, row, col;
1039 char* data; 1041 char* data;
1040 double d; 1042 double d;
1041 data = GetDataOfBREC(record); 1043 data = GetDataOfBREC(record);
1042 row = Integer2Byte(data[0], data[1]); 1044 row = Integer2Byte(data[0], data[1]);
1043 col = Integer2Byte(data[2], data[3]); 1045 col = Integer2Byte(data[2], data[3]);
1044 if (data[6] == 0 && data[12] == -1 && data[13] == -1) 1046 if (data[6] == 0 && data[12] == -1 && data[13] == -1)
1045 { 1047 {
1046 // string 1048 // string
1047 } 1049 }
1048 else 1050 else
1049 if (data[6] == 1 && data[12] == -1 && data[13] == -1) 1051 if (data[6] == 1 && data[12] == -1 && data[13] == -1)
1050 { 1052 {
1051 // boolean 1053 // boolean
1052 } 1054 }
1053 else 1055 else
1054 if ( data[6] == 2 && data[12] == -1 && data[13] == -1) 1056 if ( data[6] == 2 && data[12] == -1 && data[13] == -1)
1055 { 1057 {
1056 // error 1058 // error
1057 } 1059 }
1058 else 1060 else
1059 { 1061 {
1060 // number 1062 // number
1061 xfindex = Integer2Byte(data[4], data[5]); 1063 xfindex = Integer2Byte(data[4], data[5]);
1062 d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]); 1064 d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
1063 QString s1; 1065 QString s1;
1064 int sz; 1066 int sz;
1065 sz=Integer2Byte(data[20],data[21]);// size of the formula 1067 sz=Integer2Byte(data[20],data[21]);// size of the formula
1066 char* formuladata; 1068 char* formuladata;
1067 formuladata=new char[sz]; 1069 formuladata=new char[sz];
1068 for(int w1=0;w1<sz;w1++) 1070 for(int w1=0;w1<sz;w1++)
1069 { 1071 {
1070 formuladata[w1]=data[22+w1]; 1072 formuladata[w1]=data[22+w1];
1071 }; 1073 };
1072 //22 is the first 0 idx of formula data 1074 //22 is the first 0 idx of formula data
1073 s1="="+GetFormula(row,col,sheet,formuladata,sz); 1075 s1="="+GetFormula(row,col,sheet,formuladata,sz);
1074 //printf("GetFormula:Formula=%s\r\n",s1.ascii()); 1076 //printf("GetFormula:Formula=%s\r\n",s1.ascii());
1075 sheet->Set(row,col,CellLabel(row,col,s1)); 1077 sheet->Set(row,col,CellLabel(row,col,s1));
1076 } 1078 }
1077}; 1079};
1078 1080
1079 1081
1080QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz) 1082QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz)
1081{ 1083{
1082 int length=sz; 1084 int length=sz;
1083 printf("{FormulaParser}\r\n"); 1085 printf("{FormulaParser}\r\n");
1084 printf("row=%d, col=%d, length=%d\r\n",row,col,length); 1086 printf("row=%d, col=%d, length=%d\r\n",row,col,length);
1085 int idx=0; 1087 int idx=0;
1086 int w1,w2,w3,w4; 1088 int w1,w2,w3,w4;
1087 double d1; 1089 double d1;
1088 int token; 1090 int token;
1089 QString s1; 1091 QString s1;
1090 QList <QString> operands; 1092 QList <QString> operands;
1091 operands.setAutoDelete(TRUE); 1093 operands.setAutoDelete(TRUE);
1092 QString formula; 1094 QString formula;
1093 operands.clear(); 1095 operands.clear();
1094 while( idx<length ) 1096 while( idx<length )
1095 { 1097 {
1096 token= data[idx]; idx++; 1098 token= data[idx]; idx++;
1097 switch(token) 1099 switch(token)
1098 { 1100 {
1099 case 0x1E: //prtInt 1101 case 0x1E: //prtInt
1100 w1=Integer2Byte(data[idx],data[idx+1]); 1102 w1=Integer2Byte(data[idx],data[idx+1]);
1101 idx=idx+2; 1103 idx=idx+2;
1102 operands.prepend(new QString(QString::number(w1))); 1104 operands.prepend(new QString(QString::number(w1)));
1103 printf(" token:ptgInt,num=%d\r\n",w1); 1105 printf(" token:ptgInt,num=%d\r\n",w1);
1104 break; 1106 break;
1105 case 0x1F: //ptgNumber 1107 case 0x1F: //ptgNumber
1106#if defined(__arm__) && !defined(__vfp__) 1108#if defined(__arm__) && !defined(__vfp__)
1107 d1=Double8Byte(data[idx+4],data[idx+5],data[idx+6],data[idx+7] 1109 d1=Double8Byte(data[idx+4],data[idx+5],data[idx+6],data[idx+7]
1108 ,data[idx],data[idx+1],data[idx+2],data[idx+3]); 1110 ,data[idx],data[idx+1],data[idx+2],data[idx+3]);
1109#else 1111#else
1110 d1=Double8Byte(data[idx],data[idx+1],data[idx+2],data[idx+3] 1112 d1=Double8Byte(data[idx],data[idx+1],data[idx+2],data[idx+3]
1111 ,data[idx+4],data[idx+5],data[idx+6],data[idx+7]); 1113 ,data[idx+4],data[idx+5],data[idx+6],data[idx+7]);
1112#endif 1114#endif
1113 idx=idx+8; 1115 idx=idx+8;
1114 operands.prepend(new QString(QString::number(d1))); 1116 operands.prepend(new QString(QString::number(d1)));
1115 printf(" token:ptgNumber,num=%f\r\n",d1); 1117 printf(" token:ptgNumber,num=%f\r\n",d1);
1116 break; 1118 break;
1117 case 0x17: //ptgStr 1119 case 0x17: //ptgStr
1118 if(Version==8) 1120 if(Version==8)
1119 { 1121 {
1120 //unicode string 1122 //unicode string
1121 //w1=Integer2Byte(data[idx],data[idx+1]);idx+=2; 1123 //w1=Integer2Byte(data[idx],data[idx+1]);idx+=2;
1122 w1=data[idx];idx++; 1124 w1=data[idx];idx++;
1123 printf("len=%d\r\n",w1); 1125 printf("len=%d\r\n",w1);
1124 int richruns=0; int fareastsize=0; 1126 int richruns=0; int fareastsize=0;
1125 int richstring,fareaststring; 1127 int richstring,fareaststring;
1126 int options = data[idx];idx++; 1128 int options = data[idx];idx++;
1127 fareaststring = ((options & 0x04) != 0); 1129 fareaststring = ((options & 0x04) != 0);
1128 richstring = ((options & 0x08) != 0); 1130 richstring = ((options & 0x08) != 0);
1129 if(richstring) 1131 if(richstring)
1130 { 1132 {
1131 //containts rich string formatting. 1133 //containts rich string formatting.
1132 printf("STRING:richstring\r\n"); 1134 printf("STRING:richstring\r\n");
1133 richruns= Integer2Byte(data[idx],data[idx+1]); 1135 richruns= Integer2Byte(data[idx],data[idx+1]);
1134 printf("richruns:%d\r\n",richruns); 1136 printf("richruns:%d\r\n",richruns);
1135 idx+=2; 1137 idx+=2;
1136 }; 1138 };
1137 if(fareaststring) 1139 if(fareaststring)
1138 { 1140 {
1139 //contains far east formatting 1141 //contains far east formatting
1140 printf("STRING:fareast!\r\n"); 1142 printf("STRING:fareast!\r\n");
1141 fareastsize=Integer4Byte(data[idx], data[idx+1], 1143 fareastsize=Integer4Byte(data[idx], data[idx+1],
1142 data[idx+2], data[idx+3]); 1144 data[idx+2], data[idx+3]);
1143 printf("fareastsize=%d",fareastsize); 1145 printf("fareastsize=%d",fareastsize);
1144 idx+=4; 1146 idx+=4;
1145 }; 1147 };
1146 if ((options & 0x01) == 0) //8 bit chars 1148 if ((options & 0x01) == 0) //8 bit chars
1147 { 1149 {
1148 /* ascii */ 1150 /* ascii */
1149 s1 = GetASCII(data,idx,w1); 1151 s1 = GetASCII(data,idx,w1);
1150 idx=idx+w1; 1152 idx=idx+w1;
1151 printf("STRING:ASCII=%s\r\n",s1.ascii()); 1153 printf("STRING:ASCII=%s\r\n",s1.ascii());
1152 }else //16 bit chars 1154 }else //16 bit chars
1153 { 1155 {
1154 /* unicode */ 1156 /* unicode */
1155 s1 = GetUnicode(data,idx,w1); 1157 s1 = GetUnicode(data,idx,w1);
1156 idx=idx+w1*2; 1158 idx=idx+w1*2;
1157 printf("STRING:unicode=%s\r\n",s1.ascii()); 1159 printf("STRING:unicode=%s\r\n",s1.ascii());
1158 }; 1160 };
1159 // HERE TO PUT richformat handling 1161 // HERE TO PUT richformat handling
1160 if (richstring) 1162 if (richstring)
1161 { 1163 {
1162 idx += 4 * richruns; 1164 idx += 4 * richruns;
1163 }; 1165 };
1164 if (fareaststring) 1166 if (fareaststring)
1165 { 1167 {
1166 idx += fareastsize; 1168 idx += fareastsize;
1167 }; 1169 };
1168 s1=QString("""")+s1+QString(""""); 1170 s1=QString("""")+s1+QString("""");
1169 operands.prepend(new QString(s1)); 1171 operands.prepend(new QString(s1));
1170 } 1172 }
1171 else 1173 else
1172 { 1174 {
1173 w1=data[idx];idx++; 1175 w1=data[idx];idx++;
1174 s1=GetASCII(data,idx,w1); 1176 s1=GetASCII(data,idx,w1);
1175 s1=QString("""")+s1+QString(""""); 1177 s1=QString("""")+s1+QString("""");
1176 idx=idx+w1; 1178 idx=idx+w1;
1177 operands.prepend(new QString(s1)); 1179 operands.prepend(new QString(s1));
1178 }; 1180 };
1179 printf(" token:ptgStr,num=%d\r\n",w1); 1181 printf(" token:ptgStr,num=%d\r\n",w1);
1180 break; 1182 break;
1181 case 0x25: 1183 case 0x25:
1182 case 0x45: 1184 case 0x45:
1183 case 0x65: // ptgArea 1185 case 0x65: // ptgArea
1184 if(Version==8) 1186 if(Version==8)
1185 { 1187 {
1186 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row1 1188 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row1
1187 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row2 1189 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row2
1188 w3=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col1 1190 w3=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col1
1189 w4=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col2 1191 w4=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col2
1190 } 1192 }
1191 else 1193 else
1192 { 1194 {
1193 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row1 1195 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row1
1194 w2=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row2 1196 w2=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row2
1195 w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col1 1197 w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col1
1196 w4=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col2 1198 w4=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col2
1197 }; 1199 };
1198 //ignores relative or absolute refs 1200 //ignores relative or absolute refs
1199 s1=FindCellName(w1,w3)+":"+FindCellName(w2,w4); 1201 s1=FindCellName(w1,w3)+":"+FindCellName(w2,w4);
1200 printf(" token:ptgArea,ref=%s\r\n",s1.ascii()); 1202 printf(" token:ptgArea,ref=%s\r\n",s1.ascii());
1201 operands.prepend(new QString(s1)); 1203 operands.prepend(new QString(s1));
1202 break; 1204 break;
1203 case 0x24: 1205 case 0x24:
1204 case 0x44: 1206 case 0x44:
1205 case 0x64://ptgRef 1207 case 0x64://ptgRef
1206 if(Version==8) 1208 if(Version==8)
1207 { 1209 {
1208 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row 1210 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row
1209 w2=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col 1211 w2=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col
1210 } 1212 }
1211 else 1213 else
1212 { 1214 {
1213 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row 1215 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row
1214 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col 1216 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col
1215 }; 1217 };
1216 s1=FindCellName(w1,w2); 1218 s1=FindCellName(w1,w2);
1217 printf("token:ptgRef,ref=%s\r\n",s1.ascii()); 1219 printf("token:ptgRef,ref=%s\r\n",s1.ascii());
1218 operands.prepend(new QString(s1)); 1220 operands.prepend(new QString(s1));
1219 break; 1221 break;
1220 case 0x1D: // ptgBool 1222 case 0x1D: // ptgBool
1221 w1=data[idx];idx++; 1223 w1=data[idx];idx++;
1222 printf("token:ptgBool,val=%d\r\n",w1); 1224 printf("token:ptgBool,val=%d\r\n",w1);
1223 operands.prepend(new QString(QString::number(w1))); 1225 operands.prepend(new QString(QString::number(w1)));
1224 break; 1226 break;
1225 case 0x16://ptg MissArg 1227 case 0x16://ptg MissArg
1226 printf("token:ptgMissArg, val=' '\r\n"); 1228 printf("token:ptgMissArg, val=' '\r\n");
1227 operands.prepend(new QString("0")); 1229 operands.prepend(new QString("0"));
1228 break; 1230 break;
1229 case 0x12://ptgUplus== 1231 case 0x12://ptgUplus==
1230 printf("token:ptgUplus\r\n"); 1232 printf("token:ptgUplus\r\n");
1231 s1=QString("+")+operands.first()->ascii(); 1233 s1=QString("+")+operands.first()->ascii();
1232 operands.removeFirst(); 1234 operands.removeFirst();
1233 operands.prepend(new QString(s1)); 1235 operands.prepend(new QString(s1));
1234 break; 1236 break;
1235 case 0x13://ptgUminus 1237 case 0x13://ptgUminus
1236 printf("token:ptgUminus\r\n"); 1238 printf("token:ptgUminus\r\n");
1237 s1=QString("-")+operands.first()->ascii(); 1239 s1=QString("-")+operands.first()->ascii();
1238 operands.removeFirst(); 1240 operands.removeFirst();
1239 operands.prepend(new QString(s1)); 1241 operands.prepend(new QString(s1));
1240 break; 1242 break;
1241 case 0x03://ptgAdd 1243 case 0x03://ptgAdd
1242 printf("token:ptgAdd\r\n"); 1244 printf("token:ptgAdd\r\n");
1243 operands.first(); 1245 operands.first();
1244 s1=operands.next()->ascii() 1246 s1=operands.next()->ascii()
1245 +QString("+")+operands.first()->ascii(); 1247 +QString("+")+operands.first()->ascii();
1246 operands.removeFirst();operands.removeFirst(); 1248 operands.removeFirst();operands.removeFirst();
1247 operands.prepend(new QString(s1)); 1249 operands.prepend(new QString(s1));
1248 break; 1250 break;
1249 case 0x04://ptgSub 1251 case 0x04://ptgSub
1250 printf("token:ptgSub\r\n"); 1252 printf("token:ptgSub\r\n");
1251 operands.first(); 1253 operands.first();
1252 s1=operands.next()->ascii() 1254 s1=operands.next()->ascii()
1253 +QString("-")+operands.first()->ascii(); 1255 +QString("-")+operands.first()->ascii();
1254 operands.removeFirst();operands.removeFirst(); 1256 operands.removeFirst();operands.removeFirst();
1255 operands.prepend(new QString(s1)); 1257 operands.prepend(new QString(s1));
1256 break; 1258 break;
1257 case 0x05://ptgMul 1259 case 0x05://ptgMul
1258 printf("token:ptgMul\r\n"); 1260 printf("token:ptgMul\r\n");
1259 operands.first(); 1261 operands.first();
1260 s1=operands.next()->ascii() 1262 s1=operands.next()->ascii()
1261 +QString("*")+operands.first()->ascii(); 1263 +QString("*")+operands.first()->ascii();
1262 operands.removeFirst();operands.removeFirst(); 1264 operands.removeFirst();operands.removeFirst();
1263 operands.prepend(new QString(s1)); 1265 operands.prepend(new QString(s1));
1264 break; 1266 break;
1265 case 0x06://ptgDiv 1267 case 0x06://ptgDiv
1266 printf("token:ptgDiv\r\n"); 1268 printf("token:ptgDiv\r\n");
1267 operands.first(); 1269 operands.first();
1268 s1=operands.next()->ascii() 1270 s1=operands.next()->ascii()
1269 +QString("/")+operands.first()->ascii(); 1271 +QString("/")+operands.first()->ascii();
1270 operands.removeFirst();operands.removeFirst(); 1272 operands.removeFirst();operands.removeFirst();
1271 operands.prepend(new QString(s1)); 1273 operands.prepend(new QString(s1));
1272 break; 1274 break;
1273 case 0x07://ptgPOWER 1275 case 0x07://ptgPOWER
1274 printf("token:ptgPow\r\n"); 1276 printf("token:ptgPow\r\n");
1275 operands.first(); 1277 operands.first();
1276 s1=QString("POWER(")+operands.next()->ascii() 1278 s1=QString("POWER(")+operands.next()->ascii()
1277 +QString(",")+operands.first()->ascii()+QString(")"); 1279 +QString(",")+operands.first()->ascii()+QString(")");
1278 operands.removeFirst();operands.removeFirst(); 1280 operands.removeFirst();operands.removeFirst();
1279 operands.prepend(new QString(s1)); 1281 operands.prepend(new QString(s1));
1280 break; 1282 break;
1281 case 0x08://ptgConcat 1283 case 0x08://ptgConcat
1282 printf("token:ptgConcat\r\n"); 1284 printf("token:ptgConcat\r\n");
1283 operands.first(); 1285 operands.first();
1284 s1=QString("CONCATENATE(")+operands.next()->ascii() 1286 s1=QString("CONCATENATE(")+operands.next()->ascii()
1285 +QString(",")+operands.first()->ascii()+QString(")"); 1287 +QString(",")+operands.first()->ascii()+QString(")");
1286 operands.removeFirst();operands.removeFirst(); 1288 operands.removeFirst();operands.removeFirst();
1287 operands.prepend(new QString(s1)); 1289 operands.prepend(new QString(s1));
1288 break; 1290 break;
1289 case 0x15://ptgParenthesis 1291 case 0x15://ptgParenthesis
1290 printf("token:ptgParenthesis\r\n"); 1292 printf("token:ptgParenthesis\r\n");
1291 s1=QString("(")+operands.first()->ascii()+QString(")"); 1293 s1=QString("(")+operands.first()->ascii()+QString(")");
1292 operands.removeFirst(); 1294 operands.removeFirst();
1293 operands.prepend(new QString(s1)); 1295 operands.prepend(new QString(s1));
1294 break; 1296 break;
1295 case 0x14://ptgPercent 1297 case 0x14://ptgPercent
1296 printf("token:ptgPercent\r\n"); 1298 printf("token:ptgPercent\r\n");
1297 s1=operands.first()->ascii()+QString("*0.01"); 1299 s1=operands.first()->ascii()+QString("*0.01");
1298 operands.removeFirst(); 1300 operands.removeFirst();
1299 operands.prepend(new QString(s1)); 1301 operands.prepend(new QString(s1));
1300 break; 1302 break;
1301 case 0x9://ptgLessThan 1303 case 0x9://ptgLessThan
1302 printf("token:ptgLESS\r\n"); 1304 printf("token:ptgLESS\r\n");
1303 operands.first(); 1305 operands.first();
1304 s1=operands.next()->ascii() 1306 s1=operands.next()->ascii()
1305 +QString("<")+operands.first()->ascii(); 1307 +QString("<")+operands.first()->ascii();
1306 operands.removeFirst();operands.removeFirst(); 1308 operands.removeFirst();operands.removeFirst();
1307 operands.prepend(new QString(s1)); 1309 operands.prepend(new QString(s1));
1308 break; 1310 break;
1309 case 0xa://ptgLessEqual 1311 case 0xa://ptgLessEqual
1310 printf("token:ptgLESS_EQUAL\r\n"); 1312 printf("token:ptgLESS_EQUAL\r\n");
1311 operands.first(); 1313 operands.first();
1312 s1=operands.next()->ascii() 1314 s1=operands.next()->ascii()
1313 +QString("<=")+operands.first()->ascii(); 1315 +QString("<=")+operands.first()->ascii();
1314 operands.removeFirst();operands.removeFirst(); 1316 operands.removeFirst();operands.removeFirst();
1315 operands.prepend(new QString(s1)); 1317 operands.prepend(new QString(s1));
1316 break; 1318 break;
1317 case 0xb://ptgEQUAL 1319 case 0xb://ptgEQUAL
1318 printf("token:ptgEQUAL\r\n"); 1320 printf("token:ptgEQUAL\r\n");
1319 operands.first(); 1321 operands.first();
1320 s1=operands.next()->ascii() 1322 s1=operands.next()->ascii()
1321 +QString("==")+operands.first()->ascii(); 1323 +QString("==")+operands.first()->ascii();
1322 operands.removeFirst();operands.removeFirst(); 1324 operands.removeFirst();operands.removeFirst();
1323 operands.prepend(new QString(s1)); 1325 operands.prepend(new QString(s1));
1324 break; 1326 break;
1325 case 0xc://ptgGREATER_EQUAL 1327 case 0xc://ptgGREATER_EQUAL
1326 printf("token:ptgGREAT_EQUAL\r\n"); 1328 printf("token:ptgGREAT_EQUAL\r\n");
1327 operands.first(); 1329 operands.first();
1328 s1=operands.next()->ascii() 1330 s1=operands.next()->ascii()
1329 +QString(">=")+operands.first()->ascii(); 1331 +QString(">=")+operands.first()->ascii();
1330 operands.removeFirst();operands.removeFirst(); 1332 operands.removeFirst();operands.removeFirst();
1331 operands.prepend(new QString(s1)); 1333 operands.prepend(new QString(s1));
1332 break; 1334 break;
1333 case 0xd://ptgGREAT_THAN 1335 case 0xd://ptgGREAT_THAN
1334 printf("token:ptgGREAT_THAN\r\n"); 1336 printf("token:ptgGREAT_THAN\r\n");
1335 operands.first(); 1337 operands.first();
1336 s1=operands.next()->ascii() 1338 s1=operands.next()->ascii()
1337 +QString(">")+operands.first()->ascii(); 1339 +QString(">")+operands.first()->ascii();
1338 operands.removeFirst();operands.removeFirst(); 1340 operands.removeFirst();operands.removeFirst();
1339 operands.prepend(new QString(s1)); 1341 operands.prepend(new QString(s1));
1340 break; 1342 break;
1341 case 0xe://ptgNOT_EQUAL 1343 case 0xe://ptgNOT_EQUAL
1342 printf("token:ptgNOTequal\r\n"); 1344 printf("token:ptgNOTequal\r\n");
1343 operands.first(); 1345 operands.first();
1344 s1=operands.next()->ascii() 1346 s1=operands.next()->ascii()
1345 +QString("!=")+operands.first()->ascii(); 1347 +QString("!=")+operands.first()->ascii();
1346 operands.removeFirst();operands.removeFirst(); 1348 operands.removeFirst();operands.removeFirst();
1347 operands.prepend(new QString(s1)); 1349 operands.prepend(new QString(s1));
1348 break; 1350 break;
1349 case 0x19://attribute can be Sum,If,Choose 1351 case 0x19://attribute can be Sum,If,Choose
1350 w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; 1352 w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
1351 idx++; 1353 idx++;
1352 printf("token:ATTRIBUTE:0x%x\r\n",w3); 1354 printf("token:ATTRIBUTE:0x%x\r\n",w3);
1353 for(w4=idx;w4<length;w4++) 1355 for(w4=idx;w4<length;w4++)
1354 printf("0x%x, ",data[w4]); 1356 printf("0x%x, ",data[w4]);
1355 if(w3&0x01)//choose 1357 if(w3&0x01)//choose
1356 { 1358 {
1357 printf("token:CHOOSE\r\n"); 1359 printf("token:CHOOSE\r\n");
1358 } 1360 }
1359 else if(w3&0x02)//if 1361 else if(w3&0x02)//if
1360 { 1362 {
1361 printf("token:IF\r\n"); 1363 printf("token:IF\r\n");
1362 } 1364 }
1363 else if(w3&0x10)//sum 1365 else if(w3&0x10)//sum
1364 { 1366 {
1365 printf("token:SUM\r\n"); 1367 printf("token:SUM\r\n");
1366 }; 1368 };
1367 1369
1368 break; 1370 break;
1369 1371
1370 1372
1371 case 0x21: 1373 case 0x21:
1372 case 0x22: 1374 case 0x22:
1373 case 0x42: 1375 case 0x42:
1374 case 0x62: 1376 case 0x62:
1375 case 0x41: 1377 case 0x41:
1376 case 0x61://ptgFunction 1378 case 0x61://ptgFunction
1377 printf("token:ptgFunction\r\n"); 1379 printf("token:ptgFunction\r\n");
1378 if(token==0x22||token==0x42||token==0x62) 1380 if(token==0x22||token==0x42||token==0x62)
1379 { 1381 {
1380 w2=(int)data[idx];idx++; 1382 w2=(int)data[idx];idx++;
1381 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; 1383 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
1382 } 1384 }
1383 else 1385 else
1384 { 1386 {
1385 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; 1387 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
1386 }; 1388 };
1387 switch(w1) 1389 switch(w1)
1388 { 1390 {
1389 case 0xf://SIN 1391 case 0xf://SIN
1390 s1=QString("SIN(")+operands.first()->ascii()+QString(")"); 1392 s1=QString("SIN(")+operands.first()->ascii()+QString(")");
1391 operands.removeFirst(); 1393 operands.removeFirst();
1392 operands.prepend(new QString(s1)); 1394 operands.prepend(new QString(s1));
1393 break; 1395 break;
1394 case 0x10://COS 1396 case 0x10://COS
1395 s1=QString("COS(")+operands.first()->ascii()+QString(")"); 1397 s1=QString("COS(")+operands.first()->ascii()+QString(")");
1396 operands.removeFirst(); 1398 operands.removeFirst();
1397 operands.prepend(new QString(s1)); 1399 operands.prepend(new QString(s1));
1398 break; 1400 break;
1399 case 0x11://tan 1401 case 0x11://tan
1400 s1=QString("TAN(")+operands.first()->ascii()+QString(")"); 1402 s1=QString("TAN(")+operands.first()->ascii()+QString(")");
1401 operands.removeFirst(); 1403 operands.removeFirst();
1402 operands.prepend(new QString(s1)); 1404 operands.prepend(new QString(s1));
1403 break; 1405 break;
1404 case 0x62://asin 1406 case 0x62://asin
1405 s1=QString("ASIN(")+operands.first()->ascii()+QString(")"); 1407 s1=QString("ASIN(")+operands.first()->ascii()+QString(")");
1406 operands.removeFirst(); 1408 operands.removeFirst();
1407 operands.prepend(new QString(s1)); 1409 operands.prepend(new QString(s1));
1408 break; 1410 break;
1409 case 0x63://ACOS 1411 case 0x63://ACOS
1410 s1=QString("ACOS(")+operands.first()->ascii()+QString(")"); 1412 s1=QString("ACOS(")+operands.first()->ascii()+QString(")");
1411 operands.removeFirst(); 1413 operands.removeFirst();
1412 operands.prepend(new QString(s1)); 1414 operands.prepend(new QString(s1));
1413 break; 1415 break;
1414 case 0x12://ATAN 1416 case 0x12://ATAN
1415 s1=QString("ATAN(")+operands.first()->ascii()+QString(")"); 1417 s1=QString("ATAN(")+operands.first()->ascii()+QString(")");
1416 operands.removeFirst(); 1418 operands.removeFirst();
1417 operands.prepend(new QString(s1)); 1419 operands.prepend(new QString(s1));
1418 break; 1420 break;
1419 case 0xe5://SINH 1421 case 0xe5://SINH
1420 s1=QString("SINH(")+operands.first()->ascii()+QString(")"); 1422 s1=QString("SINH(")+operands.first()->ascii()+QString(")");
1421 operands.removeFirst(); 1423 operands.removeFirst();
1422 operands.prepend(new QString(s1)); 1424 operands.prepend(new QString(s1));
1423 break; 1425 break;
1424 case 0xe6://COSH 1426 case 0xe6://COSH
1425 s1=QString("COSH(")+operands.first()->ascii()+QString(")"); 1427 s1=QString("COSH(")+operands.first()->ascii()+QString(")");
1426 operands.removeFirst(); 1428 operands.removeFirst();
1427 operands.prepend(new QString(s1)); 1429 operands.prepend(new QString(s1));
1428 break; 1430 break;
1429 case 0xe7://TANH 1431 case 0xe7://TANH
1430 s1=QString("TANH(")+operands.first()->ascii()+QString(")"); 1432 s1=QString("TANH(")+operands.first()->ascii()+QString(")");
1431 operands.removeFirst(); 1433 operands.removeFirst();
1432 operands.prepend(new QString(s1)); 1434 operands.prepend(new QString(s1));
1433 break; 1435 break;
1434 case 0xe8://ASINH 1436 case 0xe8://ASINH
1435 s1=QString("ASINH(")+operands.first()->ascii()+QString(")"); 1437 s1=QString("ASINH(")+operands.first()->ascii()+QString(")");
1436 operands.removeFirst(); 1438 operands.removeFirst();
1437 operands.prepend(new QString(s1)); 1439 operands.prepend(new QString(s1));
1438 break; 1440 break;
1439 case 0xe9://ACOSH 1441 case 0xe9://ACOSH
1440 s1=QString("ACOSH(")+operands.first()->ascii()+QString(")"); 1442 s1=QString("ACOSH(")+operands.first()->ascii()+QString(")");
1441 operands.removeFirst(); 1443 operands.removeFirst();
1442 operands.prepend(new QString(s1)); 1444 operands.prepend(new QString(s1));
1443 break; 1445 break;
1444 case 0xea://ATANH 1446 case 0xea://ATANH
1445 s1=QString("ATANH(")+operands.first()->ascii()+QString(")"); 1447 s1=QString("ATANH(")+operands.first()->ascii()+QString(")");
1446 operands.removeFirst(); 1448 operands.removeFirst();
1447 operands.prepend(new QString(s1)); 1449 operands.prepend(new QString(s1));
1448 break; 1450 break;
1449 case 0x13://pi 1451 case 0x13://pi
1450 s1="PI()"; 1452 s1="PI()";
1451 operands.prepend(new QString(s1)); 1453 operands.prepend(new QString(s1));
1452 break; 1454 break;
1453 case 0x14://sqrt 1455 case 0x14://sqrt
1454 s1=QString("SQRT(")+operands.first()->ascii()+QString(")"); 1456 s1=QString("SQRT(")+operands.first()->ascii()+QString(")");
1455 operands.removeFirst(); 1457 operands.removeFirst();
1456 operands.prepend(new QString(s1)); 1458 operands.prepend(new QString(s1));
1457 break; 1459 break;
1458 case 0x15://exp 1460 case 0x15://exp
1459 s1=QString("EXP(")+operands.first()->ascii()+QString(")"); 1461 s1=QString("EXP(")+operands.first()->ascii()+QString(")");
1460 operands.removeFirst(); 1462 operands.removeFirst();
1461 operands.prepend(new QString(s1)); 1463 operands.prepend(new QString(s1));
1462 break; 1464 break;
1463 case 0x16://LN 1465 case 0x16://LN
1464 s1=QString("LN(")+operands.first()->ascii()+QString(")"); 1466 s1=QString("LN(")+operands.first()->ascii()+QString(")");
1465 operands.removeFirst(); 1467 operands.removeFirst();
1466 operands.prepend(new QString(s1)); 1468 operands.prepend(new QString(s1));
1467 break; 1469 break;
1468 case 0x17://LOG10 1470 case 0x17://LOG10
1469 s1=QString("LOG10(")+operands.first()->ascii()+QString(")"); 1471 s1=QString("LOG10(")+operands.first()->ascii()+QString(")");
1470 operands.removeFirst(); 1472 operands.removeFirst();
1471 operands.prepend(new QString(s1)); 1473 operands.prepend(new QString(s1));
1472 break; 1474 break;
1473 case 0x18://ABS 1475 case 0x18://ABS
1474 s1=QString("ABS(")+operands.first()->ascii()+QString(")"); 1476 s1=QString("ABS(")+operands.first()->ascii()+QString(")");
1475 operands.removeFirst(); 1477 operands.removeFirst();
1476 operands.prepend(new QString(s1)); 1478 operands.prepend(new QString(s1));
1477 break; 1479 break;
1478 case 0x19://int 1480 case 0x19://int
1479 s1=QString("INT(")+operands.first()->ascii()+QString(")"); 1481 s1=QString("INT(")+operands.first()->ascii()+QString(")");
1480 operands.removeFirst(); 1482 operands.removeFirst();
1481 operands.prepend(new QString(s1)); 1483 operands.prepend(new QString(s1));
1482 break; 1484 break;
1483 case 0x1a://sign 1485 case 0x1a://sign
1484 s1=QString("SIGN(")+operands.first()->ascii()+QString(")"); 1486 s1=QString("SIGN(")+operands.first()->ascii()+QString(")");
1485 operands.removeFirst(); 1487 operands.removeFirst();
1486 operands.prepend(new QString(s1)); 1488 operands.prepend(new QString(s1));
1487 break; 1489 break;
1488 case 0x1b://round 1490 case 0x1b://round
1489 operands.first(); 1491 operands.first();
1490 s1=QString("ROUND(")+operands.next()->ascii() 1492 s1=QString("ROUND(")+operands.next()->ascii()
1491 +QString(",")+operands.first()->ascii() 1493 +QString(",")+operands.first()->ascii()
1492 +QString(")"); 1494 +QString(")");
1493 operands.removeFirst();operands.removeFirst(); 1495 operands.removeFirst();operands.removeFirst();
1494 operands.prepend(new QString(s1)); 1496 operands.prepend(new QString(s1));
1495 break; 1497 break;
1496 case 0x1d://index 1498 case 0x1d://index
1497 operands.first(); 1499 operands.first();
1498 s1=QString("INDEX(")+operands.next()->ascii() 1500 s1=QString("INDEX(")+operands.next()->ascii()
1499 +QString(",") 1501 +QString(",")
1500 +operands.first()->ascii()+QString(")"); 1502 +operands.first()->ascii()+QString(")");
1501 operands.removeFirst(); 1503 operands.removeFirst();
1502 operands.removeFirst(); 1504 operands.removeFirst();
1503 operands.prepend(new QString(s1)); 1505 operands.prepend(new QString(s1));
1504 break; 1506 break;
1505 case 0x1: // if ATTRIBUTE 1507 case 0x1: // if ATTRIBUTE
1506 operands.first();operands.next(); 1508 operands.first();operands.next();
1507 s1=QString("IF(")+operands.next()->ascii()+QString(","); 1509 s1=QString("IF(")+operands.next()->ascii()+QString(",");
1508 operands.first(); 1510 operands.first();
1509 s1=s1+operands.next()->ascii()+QString(","); 1511 s1=s1+operands.next()->ascii()+QString(",");
1510 s1=s1+operands.first()->ascii()+QString(")"); 1512 s1=s1+operands.first()->ascii()+QString(")");
1511 operands.removeFirst(); 1513 operands.removeFirst();
1512 operands.removeFirst(); 1514 operands.removeFirst();
1513 operands.removeFirst(); 1515 operands.removeFirst();
1514 operands.prepend(new QString(s1)); 1516 operands.prepend(new QString(s1));
1515 break; 1517 break;
1516 case 0x81://isblank 1518 case 0x81://isblank
1517 s1=QString("ISBLANK(")+operands.first()->ascii() 1519 s1=QString("ISBLANK(")+operands.first()->ascii()
1518 +QString(")"); 1520 +QString(")");
1519 operands.removeFirst(); 1521 operands.removeFirst();
1520 operands.prepend(new QString(s1)); 1522 operands.prepend(new QString(s1));
1521 break; 1523 break;
1522 case 0x80://isnumber 1524 case 0x80://isnumber
1523 s1=QString("ISNUMBER(")+operands.first()->ascii() 1525 s1=QString("ISNUMBER(")+operands.first()->ascii()
1524 +QString(")"); 1526 +QString(")");
1525 operands.removeFirst(); 1527 operands.removeFirst();
1526 operands.prepend(new QString(s1)); 1528 operands.prepend(new QString(s1));
1527 break; 1529 break;
1528 case 0x120://ceiling 1530 case 0x120://ceiling
1529 operands.first(); 1531 operands.first();
1530 s1=QString("CEILING(")+operands.next()->ascii() 1532 s1=QString("CEILING(")+operands.next()->ascii()
1531 +QString(",")+operands.first()->ascii() 1533 +QString(",")+operands.first()->ascii()
1532 +QString(")"); 1534 +QString(")");
1533 operands.removeFirst();operands.removeFirst(); 1535 operands.removeFirst();operands.removeFirst();
1534 operands.prepend(new QString(s1)); 1536 operands.prepend(new QString(s1));
1535 break; 1537 break;
1536 case 0x11d://floor 1538 case 0x11d://floor
1537 operands.first(); 1539 operands.first();
1538 s1=QString("FLOOR(")+operands.next()->ascii() 1540 s1=QString("FLOOR(")+operands.next()->ascii()
1539 +QString(",")+operands.first()->ascii() 1541 +QString(",")+operands.first()->ascii()
1540 +QString(")"); 1542 +QString(")");
1541 operands.removeFirst();operands.removeFirst(); 1543 operands.removeFirst();operands.removeFirst();
1542 operands.prepend(new QString(s1)); 1544 operands.prepend(new QString(s1));
1543 break; 1545 break;
1544 case 0x157://degrees 1546 case 0x157://degrees
1545 s1=QString("DEGREES(")+operands.first()->ascii() 1547 s1=QString("DEGREES(")+operands.first()->ascii()
1546 +QString(")"); 1548 +QString(")");
1547 operands.removeFirst(); 1549 operands.removeFirst();
1548 operands.prepend(new QString(s1)); 1550 operands.prepend(new QString(s1));
1549 break; 1551 break;
1550 case 0x156://radians 1552 case 0x156://radians
1551 s1=QString("RADIANS(")+operands.first()->ascii() 1553 s1=QString("RADIANS(")+operands.first()->ascii()
1552 +QString(")"); 1554 +QString(")");
1553 operands.removeFirst(); 1555 operands.removeFirst();
1554 operands.prepend(new QString(s1)); 1556 operands.prepend(new QString(s1));
1555 break; 1557 break;
1556 case 0xb8://fact 1558 case 0xb8://fact
1557 s1=QString("FACT(")+operands.first()->ascii() 1559 s1=QString("FACT(")+operands.first()->ascii()
1558 +QString(")"); 1560 +QString(")");
1559 operands.removeFirst(); 1561 operands.removeFirst();
1560 operands.prepend(new QString(s1)); 1562 operands.prepend(new QString(s1));
1561 break; 1563 break;
1562 case 0x27://MOD 1564 case 0x27://MOD
1563 operands.first(); 1565 operands.first();
1564 s1=QString("MOD(")+operands.next()->ascii() 1566 s1=QString("MOD(")+operands.next()->ascii()
1565 +QString(",")+operands.first()->ascii() 1567 +QString(",")+operands.first()->ascii()
1566 +QString(")"); 1568 +QString(")");
1567 operands.removeFirst();operands.removeFirst(); 1569 operands.removeFirst();operands.removeFirst();
1568 operands.prepend(new QString(s1)); 1570 operands.prepend(new QString(s1));
1569 break; 1571 break;
1570 case 0x151://power 1572 case 0x151://power
1571 operands.first(); 1573 operands.first();
1572 s1=QString("POWER(")+operands.next()->ascii() 1574 s1=QString("POWER(")+operands.next()->ascii()
1573 +QString(",")+operands.first()->ascii() 1575 +QString(",")+operands.first()->ascii()
1574 +QString(")"); 1576 +QString(")");
1575 operands.removeFirst();operands.removeFirst(); 1577 operands.removeFirst();operands.removeFirst();
1576 operands.prepend(new QString(s1)); 1578 operands.prepend(new QString(s1));
1577 break; 1579 break;
1578 case 0x3f://rand() 1580 case 0x3f://rand()
1579 s1="RAND()"; 1581 s1="RAND()";
1580 operands.prepend(new QString(s1)); 1582 operands.prepend(new QString(s1));
1581 break; 1583 break;
1582 case 0x4://sum 1584 case 0x4://sum
1583 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1585 for(w4=1;w4<w2;w4++) operands.removeFirst();
1584 s1=QString("SUM(")+operands.first()->ascii() 1586 s1=QString("SUM(")+operands.first()->ascii()
1585 +QString(")"); 1587 +QString(")");
1586 operands.removeFirst(); 1588 operands.removeFirst();
1587 operands.prepend(new QString(s1)); 1589 operands.prepend(new QString(s1));
1588 break; 1590 break;
1589 case 0x6://min 1591 case 0x6://min
1590 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1592 for(w4=1;w4<w2;w4++) operands.removeFirst();
1591 s1=QString("MIN(")+operands.first()->ascii() 1593 s1=QString("MIN(")+operands.first()->ascii()
1592 +QString(")"); 1594 +QString(")");
1593 operands.removeFirst(); 1595 operands.removeFirst();
1594 operands.prepend(new QString(s1)); 1596 operands.prepend(new QString(s1));
1595 break; 1597 break;
1596 case 0x7://max 1598 case 0x7://max
1597 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1599 for(w4=1;w4<w2;w4++) operands.removeFirst();
1598 s1=QString("MAX(")+operands.first()->ascii() 1600 s1=QString("MAX(")+operands.first()->ascii()
1599 +QString(")"); 1601 +QString(")");
1600 operands.removeFirst(); 1602 operands.removeFirst();
1601 operands.prepend(new QString(s1)); 1603 operands.prepend(new QString(s1));
1602 break; 1604 break;
1603 case 0x5://average 1605 case 0x5://average
1604 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1606 for(w4=1;w4<w2;w4++) operands.removeFirst();
1605 s1=QString("AVERAGE(")+operands.first()->ascii() 1607 s1=QString("AVERAGE(")+operands.first()->ascii()
1606 +QString(")"); 1608 +QString(")");
1607 operands.removeFirst(); 1609 operands.removeFirst();
1608 operands.prepend(new QString(s1)); 1610 operands.prepend(new QString(s1));
1609 break; 1611 break;
1610 case 0x2e://var 1612 case 0x2e://var
1611 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1613 for(w4=1;w4<w2;w4++) operands.removeFirst();
1612 s1=QString("VAR(")+operands.first()->ascii() 1614 s1=QString("VAR(")+operands.first()->ascii()
1613 +QString(")"); 1615 +QString(")");
1614 operands.removeFirst(); 1616 operands.removeFirst();
1615 operands.prepend(new QString(s1)); 1617 operands.prepend(new QString(s1));
1616 break; 1618 break;
1617 case 0xc2://varp 1619 case 0xc2://varp
1618 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1620 for(w4=1;w4<w2;w4++) operands.removeFirst();
1619 s1=QString("VARP(")+operands.first()->ascii() 1621 s1=QString("VARP(")+operands.first()->ascii()
1620 +QString(")"); 1622 +QString(")");
1621 operands.removeFirst(); 1623 operands.removeFirst();
1622 operands.prepend(new QString(s1)); 1624 operands.prepend(new QString(s1));
1623 break; 1625 break;
1624 case 0xc://stdev 1626 case 0xc://stdev
1625 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1627 for(w4=1;w4<w2;w4++) operands.removeFirst();
1626 s1=QString("STDEV(")+operands.first()->ascii() 1628 s1=QString("STDEV(")+operands.first()->ascii()
1627 +QString(")"); 1629 +QString(")");
1628 operands.removeFirst(); 1630 operands.removeFirst();
1629 operands.prepend(new QString(s1)); 1631 operands.prepend(new QString(s1));
1630 break; 1632 break;
1631 case 0xc1://stdevp 1633 case 0xc1://stdevp
1632 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1634 for(w4=1;w4<w2;w4++) operands.removeFirst();
1633 s1=QString("STDEVP(")+operands.first()->ascii() 1635 s1=QString("STDEVP(")+operands.first()->ascii()
1634 +QString(")"); 1636 +QString(")");
1635 operands.removeFirst(); 1637 operands.removeFirst();
1636 operands.prepend(new QString(s1)); 1638 operands.prepend(new QString(s1));
1637 break; 1639 break;
1638 case 0x143://skew 1640 case 0x143://skew
1639 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1641 for(w4=1;w4<w2;w4++) operands.removeFirst();
1640 s1=QString("SKEW(")+operands.first()->ascii() 1642 s1=QString("SKEW(")+operands.first()->ascii()
1641 +QString(")"); 1643 +QString(")");
1642 operands.removeFirst(); 1644 operands.removeFirst();
1643 operands.prepend(new QString(s1)); 1645 operands.prepend(new QString(s1));
1644 break; 1646 break;
1645 case 0x142://kurt 1647 case 0x142://kurt
1646 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1648 for(w4=1;w4<w2;w4++) operands.removeFirst();
1647 s1=QString("KURT(")+operands.first()->ascii() 1649 s1=QString("KURT(")+operands.first()->ascii()
1648 +QString(")"); 1650 +QString(")");
1649 operands.removeFirst(); 1651 operands.removeFirst();
1650 operands.prepend(new QString(s1)); 1652 operands.prepend(new QString(s1));
1651 break; 1653 break;
1652 case 0x0://count 1654 case 0x0://count
1653 for(w4=1;w4<w2;w4++) operands.removeFirst(); 1655 for(w4=1;w4<w2;w4++) operands.removeFirst();
1654 s1=QString("COUNT(")+operands.first()->ascii() 1656 s1=QString("COUNT(")+operands.first()->ascii()
1655 +QString(")"); 1657 +QString(")");
1656 operands.removeFirst(); 1658 operands.removeFirst();
1657 operands.prepend(new QString(s1)); 1659 operands.prepend(new QString(s1));
1658 break; 1660 break;
1659 1661
1660 default: 1662 default:
1661 printf("token:FUNCTION_UNKNOWN=0x%x\r\n",w1); 1663 printf("token:FUNCTION_UNKNOWN=0x%x\r\n",w1);
1662 return QString("FUNC_UNKNOWN"); 1664 return QString("FUNC_UNKNOWN");
1663 break; 1665 break;
1664 1666
1665 }; 1667 };
1666 1668
1667 break; 1669 break;
1668 1670
1669 default: 1671 default:
1670 printf("tokenUNKNOWN=0x%x\r\n",token); 1672 printf("tokenUNKNOWN=0x%x\r\n",token);
1671 return QString("TOKEN_UKNOWN"); 1673 return QString("TOKEN_UKNOWN");
1672 //it is dangerous to go to idx++ and not return 1674 //it is dangerous to go to idx++ and not return
1673 // because the result is unexpected. 1675 // because the result is unexpected.
1674 // but there is a possibility the the parser will give the correct 1676 // but there is a possibility the the parser will give the correct
1675 // answer, because there are some tokens in excel formulas that can be //ignored. 1677 // answer, because there are some tokens in excel formulas that can be //ignored.
1676 idx++; 1678 idx++;
1677 break; 1679 break;
1678 }; 1680 };
1679 1681
1680 }; 1682 };
1681 1683
1682 1684
1683 1685
1684 printf("{////FormulaParser}\r\n"); 1686 printf("{////FormulaParser}\r\n");
1685 printf("GetFormula:::::::r=%d,c=%d,,,%s\r\n",row,col,s1.ascii()); 1687 printf("GetFormula:::::::r=%d,c=%d,,,%s\r\n",row,col,s1.ascii());
1686 printf("\r\n"); 1688 printf("\r\n");
1687 s1=operands.first()->ascii(); 1689 s1=operands.first()->ascii();
1688 operands.clear(); 1690 operands.clear();
1689 return QString(s1); 1691 return QString(s1);
1690}; 1692};
1691 1693
1692QString ExcelBook::FindCellName(int row, int col) 1694QString ExcelBook::FindCellName(int row, int col)
1693{ 1695{
1694 row++;col++; 1696 row++;col++;
1695 QString s1=""; 1697 QString s1="";
1696 int i1=col % 26; 1698 int i1=col % 26;
1697 int i2=col / 26; 1699 int i2=col / 26;
1698 if (i2!=0) s1=(char)(i2+65); //65 =A 1700 if (i2!=0) s1=(char)(i2+65); //65 =A
1699 s1=s1+(char)(i1+65-1); 1701 s1=s1+(char)(i1+65-1);
1700 return (s1+QString::number(row)); 1702 return (s1+QString::number(row));
1701}; 1703};
1702 1704
1703 1705
1704 1706
1705 1707
1706 1708
1707 1709
1708 1710
1709 1711
diff --git a/noncore/apps/zsafe/zsafe.cpp b/noncore/apps/zsafe/zsafe.cpp
index f70f863..9c0c6ce 100644
--- a/noncore/apps/zsafe/zsafe.cpp
+++ b/noncore/apps/zsafe/zsafe.cpp
@@ -1,3221 +1,3222 @@
1/**************************************************************************** 1/****************************************************************************
2** 2**
3** Created: Sat Apr 6 17:57:45 2002 3** Created: Sat Apr 6 17:57:45 2002
4** 4**
5** Author: Carsten Schneider <CarstenSchneider@t-online.de> 5** Author: Carsten Schneider <CarstenSchneider@t-online.de>
6** 6**
7** $Id$ 7** $Id$
8** 8**
9** Homepage: http://home.t-online.de/home/CarstenSchneider/zsafe/index.html 9** Homepage: http://home.t-online.de/home/CarstenSchneider/zsafe/index.html
10** 10**
11** 11**
12****************************************************************************/ 12****************************************************************************/
13#include "zsafe.h" 13#include "zsafe.h"
14#include "newdialog.h" 14#include "newdialog.h"
15#include "searchdialog.h" 15#include "searchdialog.h"
16#include "categorydialog.h" 16#include "categorydialog.h"
17#include "passworddialog.h" 17#include "passworddialog.h"
18#include "infoform.h" 18#include "infoform.h"
19#include "zlistview.h" 19#include "zlistview.h"
20#include "shadedlistitem.h" 20#include "shadedlistitem.h"
21 21
22#include <opie2/oresource.h> 22#include <opie2/oresource.h>
23#include <opie2/ofiledialog.h> 23#include <opie2/ofiledialog.h>
24#include <opie2/odebug.h> 24#include <opie2/odebug.h>
25using namespace Opie::Core; 25using namespace Opie::Core;
26using namespace Opie::Ui; 26using namespace Opie::Ui;
27 27
28#include <qclipboard.h> 28#include <qclipboard.h>
29 29
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32#include <fcntl.h> 32#include <fcntl.h>
33#include <stdlib.h> 33#include <stdlib.h>
34#include <unistd.h> 34#include <unistd.h>
35#include <string.h> 35#include <string.h>
36#include <errno.h> 36#include <errno.h>
37 37
38#include <qmenubar.h> 38#include <qmenubar.h>
39#include <qpopupmenu.h> 39#include <qpopupmenu.h>
40 40
41#include <qfile.h> 41#include <qfile.h>
42#include <qpe/applnk.h> 42#include <qpe/applnk.h>
43#include <qpe/global.h> 43#include <qpe/global.h>
44#include <qpe/qpeapplication.h> 44#include <qpe/qpeapplication.h>
45#include <qpe/config.h> 45#include <qpe/config.h>
46 46
47#include <qaction.h> 47#include <qaction.h>
48#include <qtimer.h> 48#include <qtimer.h>
49#include <qlayout.h> 49#include <qlayout.h>
50#include <qmessagebox.h> 50#include <qmessagebox.h>
51#include <qfile.h> 51#include <qfile.h>
52#include <qtextstream.h> 52#include <qtextstream.h>
53#include <qheader.h> 53#include <qheader.h>
54#include <qlistview.h> 54#include <qlistview.h>
55#include <qvariant.h> 55#include <qvariant.h>
56#include <qtooltip.h> 56#include <qtooltip.h>
57#include <qwhatsthis.h> 57#include <qwhatsthis.h>
58#include <qimage.h> 58#include <qimage.h>
59#include <qpixmap.h> 59#include <qpixmap.h>
60#include <qlineedit.h> 60#include <qlineedit.h>
61#include <qmultilineedit.h> 61#include <qmultilineedit.h>
62#include <qregexp.h> 62#include <qregexp.h>
63#include <qdir.h> 63#include <qdir.h>
64#include <qtextbrowser.h> 64#include <qtextbrowser.h>
65#include <qlabel.h> 65#include <qlabel.h>
66#include <qcombobox.h> 66#include <qcombobox.h>
67#include <qtoolbar.h> 67#include <qtoolbar.h>
68 68
69#include "krc2.h" 69#include "krc2.h"
70 70
71#include "wait.h" 71#include "wait.h"
72 72
73const QString APP_KEY = ""; 73const QString APP_KEY = "";
74 74
75// include xmp images 75// include xmp images
76#include "pics/zsafe/expand.xpm" 76#include "pics/zsafe/expand.xpm"
77#include "pics/zsafe/export.xpm" 77#include "pics/zsafe/export.xpm"
78#include "pics/zsafe/import.xpm" 78#include "pics/zsafe/import.xpm"
79 79
80static const char* const bank_cards_data[] = { 80static const char* const bank_cards_data[] = {
81"14 14 16 1", 81"14 14 16 1",
82". c None", 82". c None",
83"# c #000000", 83"# c #000000",
84"b c #0000de", 84"b c #0000de",
85"a c #0000e6", 85"a c #0000e6",
86"j c #41de83", 86"j c #41de83",
87"k c #4acecd", 87"k c #4acecd",
88"h c #4aced5", 88"h c #4aced5",
89"g c #5a40cd", 89"g c #5a40cd",
90"d c #5a44d5", 90"d c #5a44d5",
91"l c #9440d5", 91"l c #9440d5",
92"m c #b4ce4a", 92"m c #b4ce4a",
93"n c #cd4883", 93"n c #cd4883",
94"e c #d5ae10", 94"e c #d5ae10",
95"f c #de3ce6", 95"f c #de3ce6",
96"i c #e640e6", 96"i c #e640e6",
97"c c #ffffff", 97"c c #ffffff",
98"..............", 98"..............",
99".###########..", 99".###########..",
100".#ababababa#..", 100".#ababababa#..",
101".#babbbabbb#..", 101".#babbbabbb#..",
102".#ccccccccc#..", 102".#ccccccccc#..",
103".#cdcefcghc#..", 103".#cdcefcghc#..",
104".#ccccccccc#..", 104".#ccccccccc#..",
105".#cicjkclic#..", 105".#cicjkclic#..",
106".#ccccccccc#..", 106".#ccccccccc#..",
107".#cmchlcnec#..", 107".#cmchlcnec#..",
108".#ccccccccc#..", 108".#ccccccccc#..",
109".###########..", 109".###########..",
110"..............", 110"..............",
111".............."}; 111".............."};
112 112
113 113
114static const char* const passwords_data[] = { 114static const char* const passwords_data[] = {
115"16 16 20 1", 115"16 16 20 1",
116". c None", 116". c None",
117"# c #000000", 117"# c #000000",
118"r c #000083", 118"r c #000083",
119"p c #0000c5", 119"p c #0000c5",
120"q c #0000ff", 120"q c #0000ff",
121"n c #008100", 121"n c #008100",
122"l c #00c200", 122"l c #00c200",
123"m c #00ff00", 123"m c #00ff00",
124"j c #838100", 124"j c #838100",
125"a c #c55900", 125"a c #c55900",
126"h c #c5c200", 126"h c #c5c200",
127"o c #c5c2ff", 127"o c #c5c2ff",
128"k c #c5ffc5", 128"k c #c5ffc5",
129"f c #ff0000", 129"f c #ff0000",
130"d c #ff8100", 130"d c #ff8100",
131"b c #ffaa5a", 131"b c #ffaa5a",
132"e c #ffc2c5", 132"e c #ffc2c5",
133"c c #ffdeac", 133"c c #ffdeac",
134"i c #ffff00", 134"i c #ffff00",
135"g c #ffffc5", 135"g c #ffffc5",
136"............###.", 136"............###.",
137"...........#abb#", 137"...........#abb#",
138"..........#cbab#", 138"..........#cbab#",
139".........#cbdd#.", 139".........#cbdd#.",
140"######..#cbdd#..", 140"######..#cbdd#..",
141"#eeff#..#add#...", 141"#eeff#..#add#...",
142"#eeff#######....", 142"#eeff#######....",
143"#ccdbdd#........", 143"#ccdbdd#........",
144"#dddbdd###......", 144"#dddbdd###......",
145"#gghihhjj#......", 145"#gghihhjj#......",
146"#hhhihhjj###....", 146"#hhhihhjj###....",
147"#kklmllnnnn#....", 147"#kklmllnnnn#....",
148"#lllmllnnnn#....", 148"#lllmllnnnn#....",
149"#oopqpprprr#....", 149"#oopqpprprr#....",
150"#oopqpprprr#....", 150"#oopqpprprr#....",
151"############...."}; 151"############...."};
152 152
153static const char* const software_data[] = { 153static const char* const software_data[] = {
154"16 16 5 1", 154"16 16 5 1",
155". c None", 155". c None",
156"# c #000000", 156"# c #000000",
157"b c #838183", 157"b c #838183",
158"c c #c5ffff", 158"c c #c5ffff",
159"a c #ffffff", 159"a c #ffffff",
160"................", 160"................",
161".##############.", 161".##############.",
162"#aaaaaaaaaaaaaa#", 162"#aaaaaaaaaaaaaa#",
163"#abbbbbbbbbbbbb#", 163"#abbbbbbbbbbbbb#",
164"#ab##########ab#", 164"#ab##########ab#",
165"#ab#c########ab#", 165"#ab#c########ab#",
166"#ab#c#c######ab#", 166"#ab#c#c######ab#",
167"#ab##########ab#", 167"#ab##########ab#",
168"#ab##########ab#", 168"#ab##########ab#",
169"#ab##########ab#", 169"#ab##########ab#",
170"#ab##########ab#", 170"#ab##########ab#",
171"#ab##########ab#", 171"#ab##########ab#",
172"#aaaaaaaaaaaaab#", 172"#aaaaaaaaaaaaab#",
173"#bbbbbbbbbbbbbb#", 173"#bbbbbbbbbbbbbb#",
174".##############.", 174".##############.",
175"................"}; 175"................"};
176 176
177static const char* const general_data[] = { 177static const char* const general_data[] = {
178"14 14 98 2", 178"14 14 98 2",
179"Qt c None", 179"Qt c None",
180".k c #000000", 180".k c #000000",
181"#x c #080808", 181"#x c #080808",
182"#F c #101008", 182"#F c #101008",
183"#q c #101010", 183"#q c #101010",
184"#i c #101410", 184"#i c #101410",
185"## c #101810", 185"## c #101810",
186".m c #181818", 186".m c #181818",
187".3 c #181c18", 187".3 c #181c18",
188".I c #182018", 188".I c #182018",
189".T c #202420", 189".T c #202420",
190"#D c #202820", 190"#D c #202820",
191"#y c #292c29", 191"#y c #292c29",
192".c c #293029", 192".c c #293029",
193".d c #313031", 193".d c #313031",
194"#E c #313429", 194"#E c #313429",
195"#r c #313831", 195"#r c #313831",
196".j c #393c31", 196".j c #393c31",
197"#j c #394039", 197"#j c #394039",
198"#C c #414841", 198"#C c #414841",
199".w c #4a554a", 199".w c #4a554a",
200".a c #4a594a", 200".a c #4a594a",
201".# c #525052", 201".# c #525052",
202".l c #52594a", 202".l c #52594a",
203"#f c #525952", 203"#f c #525952",
204"#v c #525d52", 204"#v c #525d52",
205".O c #5a4c4a", 205".O c #5a4c4a",
206".9 c #5a595a", 206".9 c #5a595a",
207".A c #5a5d52", 207".A c #5a5d52",
208".B c #624c52", 208".B c #624c52",
209".0 c #625552", 209".0 c #625552",
210"#o c #626562", 210"#o c #626562",
211".R c #626962", 211".R c #626962",
212"#. c #626d5a", 212"#. c #626d5a",
213"#p c #626d62", 213"#p c #626d62",
214".2 c #627162", 214".2 c #627162",
215"#h c #6a6d62", 215"#h c #6a6d62",
216"#z c #6a7562", 216"#z c #6a7562",
217"#w c #6a756a", 217"#w c #6a756a",
218".C c #73656a", 218".C c #73656a",
219".P c #73696a", 219".P c #73696a",
220"#a c #737d6a", 220"#a c #737d6a",
221".U c #738573", 221".U c #738573",
222".E c #7b817b", 222".E c #7b817b",
223"#B c #7b857b", 223"#B c #7b857b",
224"#s c #7b897b", 224"#s c #7b897b",
225"#n c #7b917b", 225"#n c #7b917b",
226".b c #838d83", 226".b c #838d83",
227".7 c #839583", 227".7 c #839583",
228".n c #8b7d7b", 228".n c #8b7d7b",
229"#g c #8b8583", 229"#g c #8b8583",
230".g c #8b858b", 230".g c #8b858b",
231".r c #8b898b", 231".r c #8b898b",
232".s c #8b8d8b", 232".s c #8b8d8b",
233".i c #8b9183", 233".i c #8b9183",
234".8 c #8b918b", 234".8 c #8b918b",
235"#A c #8b9d8b", 235"#A c #8b9d8b",
236".S c #8ba183", 236".S c #8ba183",
237".Z c #94918b", 237".Z c #94918b",
238".N c #949994", 238".N c #949994",
239".F c #949d94", 239".F c #949d94",
240".x c #94a18b", 240".x c #94a18b",
241".v c #94a194", 241".v c #94a194",
242".Y c #94aa94", 242".Y c #94aa94",
243".h c #9c999c", 243".h c #9c999c",
244".Q c #9ca19c", 244".Q c #9ca19c",
245"#u c #9ca59c", 245"#u c #9ca59c",
246".H c #9caa9c", 246".H c #9caa9c",
247"#e c #9cb29c", 247"#e c #9cb29c",
248"#m c #a4b29c", 248"#m c #a4b29c",
249"#t c #a4b2a4", 249"#t c #a4b2a4",
250".M c #a4b69c", 250".M c #a4b69c",
251"#l c #a4b6a4", 251"#l c #a4b6a4",
252".z c #a4baa4", 252".z c #a4baa4",
253".f c #aca5ac", 253".f c #aca5ac",
254".q c #acaaac", 254".q c #acaaac",
255"#d c #acbeac", 255"#d c #acbeac",
256".6 c #acc2ac", 256".6 c #acc2ac",
257".o c #b4b2b4", 257".o c #b4b2b4",
258".t c #b4beb4", 258".t c #b4beb4",
259"#k c #b4c2ac", 259"#k c #b4c2ac",
260".5 c #b4cab4", 260".5 c #b4cab4",
261".D c #bdb6bd", 261".D c #bdb6bd",
262".G c #bdc6b4", 262".G c #bdc6b4",
263"#c c #bdceb4", 263"#c c #bdceb4",
264".X c #bdd2bd", 264".X c #bdd2bd",
265".4 c #bdd6bd", 265".4 c #bdd6bd",
266".1 c #c5bec5", 266".1 c #c5bec5",
267".e c #c5c2c5", 267".e c #c5c2c5",
268".u c #c5cac5", 268".u c #c5cac5",
269"#b c #c5d6c5", 269"#b c #c5d6c5",
270".J c #c5dec5", 270".J c #c5dec5",
271".p c #cdcacd", 271".p c #cdcacd",
272".W c #cddecd", 272".W c #cddecd",
273".L c #cde2cd", 273".L c #cde2cd",
274".K c #d5eacd", 274".K c #d5eacd",
275".V c #d5ead5", 275".V c #d5ead5",
276".y c #d5eed5", 276".y c #d5eed5",
277"QtQtQtQtQtQtQtQtQtQtQtQtQtQt", 277"QtQtQtQtQtQtQtQtQtQtQtQtQtQt",
278"QtQtQt.#.a.b.cQtQtQtQtQtQtQt", 278"QtQtQt.#.a.b.cQtQtQtQtQtQtQt",
279"QtQt.d.e.f.g.h.i.c.j.dQt.kQt", 279"QtQt.d.e.f.g.h.i.c.j.dQt.kQt",
280".a.l.m.n.o.p.q.r.s.t.u.v.wQt", 280".a.l.m.n.o.p.q.r.s.t.u.v.wQt",
281".x.y.z.A.B.C.D.p.q.E.F.G.H.I", 281".x.y.z.A.B.C.D.p.q.E.F.G.H.I",
282".I.J.K.L.M.N.O.P.o.p.Q.R.S.T", 282".I.J.K.L.M.N.O.P.o.p.Q.R.S.T",
283"Qt.U.V.L.W.X.Y.Z.0.P.1.s.2.3", 283"Qt.U.V.L.W.X.Y.Z.0.P.1.s.2.3",
284"Qt.3.X.W.4.X.5.6.7.8.9.s#.##", 284"Qt.3.X.W.4.X.5.6.7.8.9.s#.##",
285"QtQt#a.X#b#c.5.6#d#e#f#g#h#i", 285"QtQt#a.X#b#c.5.6#d#e#f#g#h#i",
286"QtQtQt#j.7#k.6#d#l#m#n#o#p#q", 286"QtQtQt#j.7#k.6#d#l#m#n#o#p#q",
287"QtQtQtQt.k#r#s#m#t.H#u#v#w#x", 287"QtQtQtQt.k#r#s#m#t.H#u#v#w#x",
288"QtQtQtQtQtQt.k#y#z.v#A#B#C#x", 288"QtQtQtQtQtQt.k#y#z.v#A#B#C#x",
289"QtQtQtQtQtQtQtQt.k#D.w#s#E.k", 289"QtQtQtQtQtQtQtQt.k#D.w#s#E.k",
290"QtQtQtQtQtQtQtQtQtQtQt#x#FQt"}; 290"QtQtQtQtQtQtQtQtQtQtQt#x#FQt"};
291 291
292// exit ZSafe and clear the clipboard for security reasons 292// exit ZSafe and clear the clipboard for security reasons
293 void ZSafe::exitZs (int ec) 293 void ZSafe::exitZs (int ec)
294 { 294 {
295 QClipboard *cb = QApplication::clipboard(); 295 QClipboard *cb = QApplication::clipboard();
296 cb->clear(); 296 cb->clear();
297 297
298 exit (ec); 298 exit (ec);
299 } 299 }
300 300
301 301
302// save the configuration into the file 302// save the configuration into the file
303 void ZSafe::saveConf () 303 void ZSafe::saveConf ()
304 { 304 {
305 if (conf) 305 if (conf)
306 { 306 {
307 delete conf; 307 delete conf;
308 308
309 conf = new Config ("zsafe"); 309 conf = new Config ("zsafe");
310 conf->setGroup ("zsafe"); 310 conf->setGroup ("zsafe");
311 } 311 }
312 } 312 }
313 313
314 314
315/* 315/*
316 * Constructs a ZSafe which is a child of 'parent', with the 316 * Constructs a ZSafe which is a child of 'parent', with the
317 * name 'name' and widget flags set to 'f' 317 * name 'name' and widget flags set to 'f'
318 * 318 *
319 * The dialog will by default be modeless, unless you set 'modal' to 319 * The dialog will by default be modeless, unless you set 'modal' to
320 * TRUE to construct a modal dialog. 320 * TRUE to construct a modal dialog.
321 */ 321 */
322ZSafe::ZSafe( QWidget* parent, const char* name, WFlags fl ) 322ZSafe::ZSafe( QWidget* parent, const char* name, WFlags fl )
323 : QMainWindow( parent, name, fl), 323 : QMainWindow( parent, name, fl),
324 ListView(0l) 324 ListView(0l)
325{ 325{
326 IsCut = false; 326 IsCut = false;
327 IsCopy = false; 327 IsCopy = false;
328 modified = false; 328 modified = false;
329 showpwd = false; 329 showpwd = false;
330 330
331 // set the config file 331 // set the config file
332 cfgFile=QDir::homeDirPath(); 332 cfgFile=QDir::homeDirPath();
333 cfgFile += "/.zsafe.cfg"; 333 cfgFile += "/.zsafe.cfg";
334 // set the icon path 334 // set the icon path
335 335
336 QString qpeDir = QPEApplication::qpeDir(); 336 QString qpeDir = QPEApplication::qpeDir();
337 337
338 conf = new Config ("zsafe"); 338 conf = new Config ("zsafe");
339 conf->setGroup ("zsafePrefs"); 339 conf->setGroup ("zsafePrefs");
340 340
341 expandTree = conf->readNumEntry(APP_KEY+"expandTree", 0); 341 expandTree = conf->readNumEntry(APP_KEY+"expandTree", 0);
342 conf->setGroup ("zsafe"); 342 conf->setGroup ("zsafe");
343 343
344 QPixmap new_img = Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ); 344 QPixmap new_img = Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon );
345 QPixmap edit_img = Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ); 345 QPixmap edit_img = Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon );
346 QPixmap trash_img = Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ); 346 QPixmap trash_img = Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon );
347 QPixmap copy_img = Opie::Core::OResource::loadPixmap( "copy", Opie::Core::OResource::SmallIcon ); 347 QPixmap copy_img = Opie::Core::OResource::loadPixmap( "copy", Opie::Core::OResource::SmallIcon );
348 QPixmap cut_img = Opie::Core::OResource::loadPixmap( "cut", Opie::Core::OResource::SmallIcon ); 348 QPixmap cut_img = Opie::Core::OResource::loadPixmap( "cut", Opie::Core::OResource::SmallIcon );
349 QPixmap editdelete_img = Opie::Core::OResource::loadPixmap( "editdelete", Opie::Core::OResource::SmallIcon ); 349 QPixmap editdelete_img = Opie::Core::OResource::loadPixmap( "editdelete", Opie::Core::OResource::SmallIcon );
350 QPixmap folder_open_img = Opie::Core::OResource::loadPixmap( "folder_open", Opie::Core::OResource::SmallIcon ); 350 QPixmap folder_open_img = Opie::Core::OResource::loadPixmap( "folder_open", Opie::Core::OResource::SmallIcon );
351 QPixmap help_icon_img = Opie::Core::OResource::loadPixmap( "help_icon", Opie::Core::OResource::SmallIcon ); 351 QPixmap help_icon_img = Opie::Core::OResource::loadPixmap( "help_icon", Opie::Core::OResource::SmallIcon );
352 QPixmap paste_img = Opie::Core::OResource::loadPixmap( "paste", Opie::Core::OResource::SmallIcon ); 352 QPixmap paste_img = Opie::Core::OResource::loadPixmap( "paste", Opie::Core::OResource::SmallIcon );
353 QPixmap save_img = Opie::Core::OResource::loadPixmap( "save", Opie::Core::OResource::SmallIcon ); 353 QPixmap save_img = Opie::Core::OResource::loadPixmap( "save", Opie::Core::OResource::SmallIcon );
354 QPixmap expand_img((const char**) expand_xpm); 354 QPixmap expand_img((const char**) expand_xpm);
355 QPixmap export_img((const char**) export_xpm); 355 QPixmap export_img((const char**) export_xpm);
356 QPixmap import_img((const char**) import_xpm); 356 QPixmap import_img((const char**) import_xpm);
357 357
358 QPixmap bank_cards( ( const char** ) bank_cards_data ); 358 QPixmap bank_cards( ( const char** ) bank_cards_data );
359 QPixmap passwords( ( const char** ) passwords_data ); 359 QPixmap passwords( ( const char** ) passwords_data );
360 QPixmap software( ( const char** ) software_data ); 360 QPixmap software( ( const char** ) software_data );
361 QPixmap general( ( const char** ) general_data ); 361 QPixmap general( ( const char** ) general_data );
362 QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon ); 362 QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon );
363 363
364 if ( !name ) 364 if ( !name )
365 setName( "ZSafe" ); 365 setName( "ZSafe" );
366 366
367 setCaption( tr( "ZSafe" ) ); 367 setCaption( tr( "ZSafe" ) );
368 QString zsafeAppDirPath = QDir::homeDirPath() + "/Documents/application/zsafe"; 368 QString zsafeAppDirPath = QDir::homeDirPath() + "/Documents/application/zsafe";
369 369
370 filename = conf->readEntry(APP_KEY+"document"); 370 filename = conf->readEntry(APP_KEY+"document");
371 if ( !QFileInfo(filename).exists() || !QDir(zsafeAppDirPath).exists() ) 371 if ( !QFileInfo(filename).exists() || !QDir(zsafeAppDirPath).exists() )
372 { 372 {
373 // check if the directory application exists, if not 373 // check if the directory application exists, if not
374 // create it 374 // create it
375 QString d1(QDir::homeDirPath() + "/Documents/application"); 375 QString d1(QDir::homeDirPath() + "/Documents/application");
376 QDir pd1(d1); 376 QDir pd1(d1);
377 if (!pd1.exists()) 377 if (!pd1.exists())
378 { 378 {
379 QDir pd2(QDir::homeDirPath() + "/Documents"); 379 QDir pd2(QDir::homeDirPath() + "/Documents");
380 if (!pd2.exists()) { 380 if (!pd2.exists()) {
381 QDir pd3(QDir::homeDirPath()); 381 QDir pd3(QDir::homeDirPath());
382 if (!pd3.mkdir("Documents", FALSE)) { 382 if (!pd3.mkdir("Documents", FALSE)) {
383 } 383 }
384 } 384 }
385 385
386 if (!pd2.mkdir("application", FALSE)) 386 if (!pd2.mkdir("application", FALSE))
387 { 387 {
388 QMessageBox::critical( 0, tr("ZSafe"), 388 QMessageBox::critical( 0, tr("ZSafe"),
389 tr("<P>Can't create directory %1</P><P>ZSafe will now exit.</P>").arg(d1)); 389 tr("<P>Can't create directory %1</P><P>ZSafe will now exit.</P>").arg(d1));
390 exitZs (1); 390 exitZs (1);
391 } 391 }
392 } 392 }
393 QString d2(QDir::homeDirPath() + "/Documents/application/zsafe"); 393 QString d2(QDir::homeDirPath() + "/Documents/application/zsafe");
394 QDir pd2(d2); 394 QDir pd2(d2);
395 if (!pd2.exists()) 395 if (!pd2.exists())
396 { 396 {
397 if (!pd1.mkdir("zsafe", FALSE)) 397 if (!pd1.mkdir("zsafe", FALSE))
398 { 398 {
399 QMessageBox::critical( 0, tr("ZSafe"), 399 QMessageBox::critical( 0, tr("ZSafe"),
400 tr("<P>Can't create directory %1</P><P>ZSafe will now exit.</P>").arg(d2)); 400 tr("<P>Can't create directory %1</P><P>ZSafe will now exit.</P>").arg(d2));
401 exitZs (1); 401 exitZs (1);
402 } 402 }
403 } 403 }
404 404
405 filename = zsafeAppDirPath + "/passwords.zsf"; 405 filename = zsafeAppDirPath + "/passwords.zsf";
406 406
407 // save the current filename to the config file 407 // save the current filename to the config file
408 conf->writeEntry(APP_KEY+"document", filename); 408 conf->writeEntry(APP_KEY+"document", filename);
409 saveConf(); 409 saveConf();
410 } 410 }
411 //if (filename == "INVALIDPWD") 411 //if (filename == "INVALIDPWD")
412 //filename = ""; 412 //filename = "";
413 413
414 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 414 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
415 this->setCaption(tr("ZSafe: ") + ti); 415 this->setCaption(tr("ZSafe: ") + ti);
416 416
417 selectedItem = NULL; 417 selectedItem = NULL;
418 lastSearchedCategory = NULL; 418 lastSearchedCategory = NULL;
419 lastSearchedItem = NULL; 419 lastSearchedItem = NULL;
420 lastSearchedName = ""; 420 lastSearchedName = "";
421 lastSearchedUsername = ""; 421 lastSearchedUsername = "";
422 lastSearchedComment = ""; 422 lastSearchedComment = "";
423 423
424 infoForm = new InfoForm(this, "show_info", TRUE); 424 infoForm = new InfoForm(this, "show_info", TRUE);
425 categoryDialog = NULL; 425 categoryDialog = NULL;
426 infoForm->setIcon( image0); 426 infoForm->setIcon( image0);
427 427
428 // Create menu and tool bar dock 428 // Create menu and tool bar dock
429 setToolBarsMovable( false ); 429 setToolBarsMovable( false );
430 QToolBar *dock = new QToolBar( this ); 430 QToolBar *dock = new QToolBar( this );
431 dock->setHorizontalStretchable( true ); 431 dock->setHorizontalStretchable( true );
432 432
433 // add a menu bar 433 // add a menu bar
434 QMenuBar *menu = new QMenuBar( dock ); 434 QMenuBar *menu = new QMenuBar( dock );
435 menu->setMargin( 0 ); 435 menu->setMargin( 0 );
436 436
437 // Add a toolbar 437 // Add a toolbar
438 QToolBar *toolbar = new QToolBar( this ); 438 QToolBar *toolbar = new QToolBar( this );
439 439
440 // add file menu 440 // add file menu
441 // QPopupMenu *file = new QPopupMenu( this ); 441 // QPopupMenu *file = new QPopupMenu( this );
442 file = new QPopupMenu( this ); 442 file = new QPopupMenu( this );
443 443
444 // File menu 444 // File menu
445 file->insertItem( new_img, tr("New document"), this, SLOT(newDocument()) ); 445 file->insertItem( new_img, tr("New document"), this, SLOT(newDocument()) );
446 file->insertItem( folder_open_img, tr("Open document"), this, SLOT(loadDocument()) ); 446 file->insertItem( folder_open_img, tr("Open document"), this, SLOT(loadDocument()) );
447 file->insertItem( save_img, tr("Save document as"), this, SLOT(saveDocumentAs()) ); 447 file->insertItem( save_img, tr("Save document as"), this, SLOT(saveDocumentAs()) );
448 file->insertSeparator(); 448 file->insertSeparator();
449 449
450 file->insertItem( save_img, tr("Save document"), this, SLOT(saveDocumentWithoutPwd()) ); 450 file->insertItem( save_img, tr("Save document"), this, SLOT(saveDocumentWithoutPwd()) );
451 file->insertItem( save_img, tr("Save document with new Password"), this, 451 file->insertItem( save_img, tr("Save document with new Password"), this,
452 SLOT(saveDocumentWithPwd()) ); 452 SLOT(saveDocumentWithPwd()) );
453 file->insertSeparator(); 453 file->insertSeparator();
454 file->insertItem( export_img, tr("Export text file"), this, SLOT(writeAllEntries()) ); 454 file->insertItem( export_img, tr("Export text file"), this, SLOT(writeAllEntries()) );
455 file->insertItem( import_img, tr("Import text file"), this, SLOT(readAllEntries()) ); 455 file->insertItem( import_img, tr("Import text file"), this, SLOT(readAllEntries()) );
456 file->insertItem( trash_img, tr("Remove text file"), this, SLOT(removeAsciiFile()) ); 456 file->insertItem( trash_img, tr("Remove text file"), this, SLOT(removeAsciiFile()) );
457 file->insertSeparator(); 457 file->insertSeparator();
458 file->insertItem( expand_img, tr("Open entries expanded"), this, 458 file->insertItem( expand_img, tr("Open entries expanded"), this,
459 SLOT(setExpandFlag()), 0, 'o'); 459 SLOT(setExpandFlag()), 0, 'o');
460 file->setItemChecked('o', expandTree); 460 file->setItemChecked('o', expandTree);
461 menu->insertItem( tr("File"), file ); 461 menu->insertItem( tr("File"), file );
462 462
463 // Category menu 463 // Category menu
464 QPopupMenu *cat = new QPopupMenu( this ); 464 QPopupMenu *cat = new QPopupMenu( this );
465 cat->insertItem( new_img, tr("New"), this, SLOT(addCategory()) ); 465 cat->insertItem( new_img, tr("New"), this, SLOT(addCategory()) );
466 cat->insertItem( edit_img, tr("Edit"), this, SLOT(editCategory()) ); 466 cat->insertItem( edit_img, tr("Edit"), this, SLOT(editCategory()) );
467 cat->insertItem( trash_img, tr("Delete"), this, SLOT(delCategory()) ); 467 cat->insertItem( trash_img, tr("Delete"), this, SLOT(delCategory()) );
468 menu->insertItem( tr("Category"), cat ); 468 menu->insertItem( tr("Category"), cat );
469 469
470 // Entry menu 470 // Entry menu
471 QPopupMenu *it = new QPopupMenu( this ); 471 QPopupMenu *it = new QPopupMenu( this );
472 it->insertItem( cut_img, tr("Cut"), this, SLOT(cutItem()) ); 472 it->insertItem( cut_img, tr("Cut"), this, SLOT(cutItem()) );
473 it->insertItem( copy_img, tr("Copy"), this, SLOT(copyItem()) ); 473 it->insertItem( copy_img, tr("Copy"), this, SLOT(copyItem()) );
474 it->insertItem( paste_img, tr("Paste"), this, SLOT(pasteItem()) ); 474 it->insertItem( paste_img, tr("Paste"), this, SLOT(pasteItem()) );
475 it->insertSeparator(); 475 it->insertSeparator();
476 476
477 QAction *a = new QAction( tr( "New" ), new_img, QString::null, 0, this, 0 ); 477 QAction *a = new QAction( tr( "New" ), new_img, QString::null, 0, this, 0 );
478 connect( a, SIGNAL(activated()), this, SLOT(newPwd()) ); 478 connect( a, SIGNAL(activated()), this, SLOT(newPwd()) );
479 a->addTo( it ); 479 a->addTo( it );
480 a->addTo( toolbar ); 480 a->addTo( toolbar );
481 a = new QAction( tr( "Edit" ), edit_img, QString::null, 0, this, 0 ); 481 a = new QAction( tr( "Edit" ), edit_img, QString::null, 0, this, 0 );
482 connect( a, SIGNAL(activated()), this, SLOT(editPwd()) ); 482 connect( a, SIGNAL(activated()), this, SLOT(editPwd()) );
483 a->addTo( it ); 483 a->addTo( it );
484 a->addTo( toolbar ); 484 a->addTo( toolbar );
485 a = new QAction( tr( "Delete" ), trash_img, QString::null, 0, this, 0 ); 485 a = new QAction( tr( "Delete" ), trash_img, QString::null, 0, this, 0 );
486 connect( a, SIGNAL(activated()), this, SLOT(deletePwd()) ); 486 connect( a, SIGNAL(activated()), this, SLOT(deletePwd()) );
487 a->addTo( it ); 487 a->addTo( it );
488 a->addTo( toolbar ); 488 a->addTo( toolbar );
489 a = new QAction( tr( "Search" ), Opie::Core::OResource::loadPixmap( "find", Opie::Core::OResource::SmallIcon ), 489 a = new QAction( tr( "Search" ), Opie::Core::OResource::loadPixmap( "find", Opie::Core::OResource::SmallIcon ),
490 QString::null, 0, this, 0 ); 490 QString::null, 0, this, 0 );
491 connect( a, SIGNAL(activated()), this, SLOT(findPwd()) ); 491 connect( a, SIGNAL(activated()), this, SLOT(findPwd()) );
492 a->addTo( it ); 492 a->addTo( it );
493 a->addTo( toolbar ); 493 a->addTo( toolbar );
494 menu->insertItem( tr("Entry"), it ); 494 menu->insertItem( tr("Entry"), it );
495 495
496 // Add main view 496 // Add main view
497 ListView = new ZListView( this, "ListView" ); 497 ListView = new ZListView( this, "ListView" );
498 ListView->addColumn( tr( "Name" ) ); 498 ListView->addColumn( tr( "Name" ) );
499 ListView->addColumn( tr( "Field 2" ) ); 499 ListView->addColumn( tr( "Field 2" ) );
500 ListView->addColumn( tr( "Field 3" ) ); 500 ListView->addColumn( tr( "Field 3" ) );
501 ListView->addColumn( tr( "Comment" ) ); 501 ListView->addColumn( tr( "Comment" ) );
502 ListView->addColumn( tr( "Field 4" ) ); 502 ListView->addColumn( tr( "Field 4" ) );
503 ListView->addColumn( tr( "Field 5" ) ); 503 ListView->addColumn( tr( "Field 5" ) );
504 ListView->setAllColumnsShowFocus(TRUE); 504 ListView->setAllColumnsShowFocus(TRUE);
505 505
506 ListView->setResizePolicy(QScrollView::AutoOneFit); 506 ListView->setResizePolicy(QScrollView::AutoOneFit);
507 setCentralWidget( ListView ); 507 setCentralWidget( ListView );
508 508
509 QBoxLayout * l = new QVBoxLayout( this ); 509 QBoxLayout * l = new QVBoxLayout( this );
510 l->addWidget (menu); 510 l->addWidget (menu);
511 l->addWidget (ListView); 511 l->addWidget (ListView);
512 512
513 // start a timer (100 ms) to load the default document 513 // start a timer (100 ms) to load the default document
514 docuTimer.start( 100, true ); 514 docuTimer.start( 100, true );
515 connect( &docuTimer, SIGNAL(timeout()), SLOT( slotLoadDocu() ) ); 515 connect( &docuTimer, SIGNAL(timeout()), SLOT( slotLoadDocu() ) );
516 raiseFlag = true; 516 raiseFlag = true;
517 connect( &raiseTimer, SIGNAL(timeout()), SLOT( slotRaiseTimer() ) ); 517 connect( &raiseTimer, SIGNAL(timeout()), SLOT( slotRaiseTimer() ) );
518 518
519 // signals and slots connections for QListView 519 // signals and slots connections for QListView
520 connect( ListView, SIGNAL( selectionChanged(QListViewItem*) ), 520 connect( ListView, SIGNAL( selectionChanged(QListViewItem*) ),
521 this, SLOT( listViewSelected(QListViewItem*) ) ); 521 this, SLOT( listViewSelected(QListViewItem*) ) );
522 connect( ListView, SIGNAL( doubleClicked(QListViewItem*) ), 522 connect( ListView, SIGNAL( doubleClicked(QListViewItem*) ),
523 this, SLOT( showInfo(QListViewItem*) ) ); 523 this, SLOT( showInfo(QListViewItem*) ) );
524 connect( ListView, SIGNAL( returnPressed(QListViewItem*) ), 524 connect( ListView, SIGNAL( returnPressed(QListViewItem*) ),
525 this, SLOT( showInfo(QListViewItem*) ) ); 525 this, SLOT( showInfo(QListViewItem*) ) );
526 526
527 QPEApplication::setStylusOperation( ListView->viewport(),QPEApplication::RightOnHold); 527 QPEApplication::setStylusOperation( ListView->viewport(),QPEApplication::RightOnHold);
528 connect( ListView, SIGNAL( mouseButtonPressed( int, QListViewItem *, const QPoint&, int)), 528 connect( ListView, SIGNAL( mouseButtonPressed( int, QListViewItem *, const QPoint&, int)),
529 this,SLOT( ListPressed(int, QListViewItem *, const QPoint&, int)) ); 529 this,SLOT( ListPressed(int, QListViewItem *, const QPoint&, int)) );
530 530
531 this->setIcon( image0); 531 this->setIcon( image0);
532} 532}
533 533
534const QColor *ZSafe::evenRowColor = &Qt::white; 534const QColor *ZSafe::evenRowColor = &Qt::white;
535// const QColor *ZSafe::oddRowColor = &Qt::lightGray; 535// const QColor *ZSafe::oddRowColor = &Qt::lightGray;
536const QColor *ZSafe::oddRowColor = new QColor(216,240,255); 536const QColor *ZSafe::oddRowColor = new QColor(216,240,255);
537 537
538/* 538/*
539 * Destroys the object and frees any allocated resources 539 * Destroys the object and frees any allocated resources
540 */ 540 */
541ZSafe::~ZSafe() 541ZSafe::~ZSafe()
542{ 542{
543 // no need to delete child widgets, Qt does it all for us 543 // no need to delete child widgets, Qt does it all for us
544 quitMe(); 544 quitMe();
545} 545}
546 546
547// load the default document 547// load the default document
548void ZSafe::slotLoadDocu() 548void ZSafe::slotLoadDocu()
549{ 549{
550 openDocument (filename); 550 openDocument (filename);
551} 551}
552 552
553void ZSafe::deletePwd() 553void ZSafe::deletePwd()
554{ 554{
555 555
556 if (!selectedItem) 556 if (!selectedItem)
557 return; 557 return;
558 if (!isCategory(selectedItem)) 558 if (!isCategory(selectedItem))
559 { 559 {
560 switch( QMessageBox::information( this, tr("ZSafe"), 560 switch( QMessageBox::information( this, tr("ZSafe"),
561 tr("Do you want to delete?"), 561 tr("Do you want to delete?"),
562 tr("&Delete"), tr("D&on't Delete"), 562 tr("&Delete"), tr("D&on't Delete"),
563 0 // Enter == button 0 563 0 // Enter == button 0
564 ) ) { // Escape == button 2 564 ) ) { // Escape == button 2
565 case 0: // Delete clicked, Alt-S or Enter pressed. 565 case 0: // Delete clicked, Alt-S or Enter pressed.
566 // Delete 566 // Delete
567 modified = true; 567 modified = true;
568 selectedItem->parent()->takeItem(selectedItem); 568 selectedItem->parent()->takeItem(selectedItem);
569 selectedItem = NULL; 569 selectedItem = NULL;
570 break; 570 break;
571 case 1: // Don't delete 571 case 1: // Don't delete
572 break; 572 break;
573 } 573 }
574 } 574 }
575 else 575 else
576 { 576 {
577 delCategory(); 577 delCategory();
578 } 578 }
579} 579}
580 580
581void ZSafe::editPwd() 581void ZSafe::editPwd()
582{ 582{
583 if (!selectedItem) 583 if (!selectedItem)
584 return; 584 return;
585 if (!isCategory(selectedItem)) 585 if (!isCategory(selectedItem))
586 { 586 {
587 // open the 'New Entry' dialog 587 // open the 'New Entry' dialog
588 NewDialog *dialog = new NewDialog(this, "edit_entry", TRUE); 588 NewDialog *dialog = new NewDialog(this, "edit_entry", TRUE);
589 589
590 // set the labels 590 // set the labels
591 dialog->Name->setText(getFieldLabel (selectedItem, "1", tr("Name"))); 591 dialog->Name->setText(getFieldLabel (selectedItem, "1", tr("Name")));
592 dialog->Username->setText(getFieldLabel (selectedItem, "2", tr("Username"))); 592 dialog->Username->setText(getFieldLabel (selectedItem, "2", tr("Username")));
593 dialog->Password->setText(getFieldLabel (selectedItem, "3", tr("Password"))); 593 dialog->Password->setText(getFieldLabel (selectedItem, "3", tr("Password")));
594 dialog->Comment->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); 594 dialog->Comment->setText(getFieldLabel (selectedItem, "4", tr("Comment")));
595 dialog->Field5Label->setText(getFieldLabel (selectedItem,"5", tr("Field 4"))); 595 dialog->Field5Label->setText(getFieldLabel (selectedItem,"5", tr("Field 4")));
596 dialog->Field6Label->setText(getFieldLabel (selectedItem,"6", tr("Field 5"))); 596 dialog->Field6Label->setText(getFieldLabel (selectedItem,"6", tr("Field 5")));
597 597
598 // set the fields 598 // set the fields
599 dialog->NameField->setText(selectedItem->text (0)); 599 dialog->NameField->setText(selectedItem->text (0));
600 dialog->UsernameField->setText(selectedItem->text (1)); 600 dialog->UsernameField->setText(selectedItem->text (1));
601 dialog->PasswordField->setText(selectedItem->text (2)); 601 dialog->PasswordField->setText(selectedItem->text (2));
602 QString comment = selectedItem->text (3); 602 QString comment = selectedItem->text (3);
603 comment.replace (QRegExp("<br>"), "\n"); 603 comment.replace (QRegExp("<br>"), "\n");
604 dialog->Field5->setText(selectedItem->text (4)); 604 dialog->Field5->setText(selectedItem->text (4));
605 dialog->Field6->setText(selectedItem->text (5)); 605 dialog->Field6->setText(selectedItem->text (5));
606 dialog->CommentField->insertLine(comment); 606 dialog->CommentField->insertLine(comment);
607 dialog->CommentField->setCursorPosition(0,0); 607 dialog->CommentField->setCursorPosition(0,0);
608 608
609 QDialog::DialogCode result = (QDialog::DialogCode) QPEApplication::execDialog( dialog ); 609 QDialog::DialogCode result = (QDialog::DialogCode) QPEApplication::execDialog( dialog );
610 if (result == QDialog::Accepted) 610 if (result == QDialog::Accepted)
611 { 611 {
612 modified = true; 612 modified = true;
613 // edit the selected item 613 // edit the selected item
614 QString name = dialog->NameField->text(); 614 QString name = dialog->NameField->text();
615 selectedItem->setText (0, tr (name)); 615 selectedItem->setText (0, tr (name));
616 QString user = dialog->UsernameField->text(); 616 QString user = dialog->UsernameField->text();
617 selectedItem->setText (1, tr (user)); 617 selectedItem->setText (1, tr (user));
618 QString pwd = dialog->PasswordField->text(); 618 QString pwd = dialog->PasswordField->text();
619 selectedItem->setText (2, tr (pwd)); 619 selectedItem->setText (2, tr (pwd));
620 QString comment = dialog->CommentField->text(); 620 QString comment = dialog->CommentField->text();
621 comment.replace (QRegExp("\n"), "<br>"); 621 comment.replace (QRegExp("\n"), "<br>");
622 selectedItem->setText (3, tr (comment)); 622 selectedItem->setText (3, tr (comment));
623 QString f5 = dialog->Field5->text(); 623 QString f5 = dialog->Field5->text();
624 selectedItem->setText (4, tr (f5)); 624 selectedItem->setText (4, tr (f5));
625 QString f6 = dialog->Field6->text(); 625 QString f6 = dialog->Field6->text();
626 selectedItem->setText (5, tr (f6)); 626 selectedItem->setText (5, tr (f6));
627 } 627 }
628 628
629 delete dialog; 629 delete dialog;
630 } 630 }
631 else 631 else
632 { 632 {
633 editCategory(); 633 editCategory();
634 } 634 }
635} 635}
636 636
637void ZSafe::newPwd() 637void ZSafe::newPwd()
638{ 638{
639 if (!selectedItem) 639 if (!selectedItem)
640 return; 640 return;
641 qWarning("new item"); 641 qWarning("new item");
642 if (!isCategory(selectedItem)) 642 if (!isCategory(selectedItem))
643 selectedItem = selectedItem->parent(); 643 selectedItem = selectedItem->parent();
644 644
645 if (isCategory(selectedItem)) 645 if (isCategory(selectedItem))
646 { 646 {
647 QString cat = selectedItem->text(0); 647 QString cat = selectedItem->text(0);
648 qWarning(cat); 648 qWarning(cat);
649 // open the 'New Entry' dialog 649 // open the 'New Entry' dialog
650 NewDialog *dialog = new NewDialog(this, "new_entry", TRUE); 650 NewDialog *dialog = new NewDialog(this, "new_entry", TRUE);
651 // set the labels 651 // set the labels
652 dialog->Name->setText(getFieldLabel (selectedItem, "1", tr("Name"))); 652 dialog->Name->setText(getFieldLabel (selectedItem, "1", tr("Name")));
653 dialog->Username->setText(getFieldLabel (selectedItem, "2", tr("Username"))); 653 dialog->Username->setText(getFieldLabel (selectedItem, "2", tr("Username")));
654 dialog->Password->setText(getFieldLabel (selectedItem, "3", tr("Password"))); 654 dialog->Password->setText(getFieldLabel (selectedItem, "3", tr("Password")));
655 dialog->Comment->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); 655 dialog->Comment->setText(getFieldLabel (selectedItem, "4", tr("Comment")));
656 dialog->Field5Label->setText(getFieldLabel (selectedItem,"5", tr("Field 4"))); 656 dialog->Field5Label->setText(getFieldLabel (selectedItem,"5", tr("Field 4")));
657 dialog->Field6Label->setText(getFieldLabel (selectedItem,"6", tr("Field 5"))); 657 dialog->Field6Label->setText(getFieldLabel (selectedItem,"6", tr("Field 5")));
658retype: 658retype:
659 659
660#ifdef Q_WS_QWS 660#ifdef Q_WS_QWS
661 QDialog::DialogCode result = (QDialog::DialogCode) QPEApplication::execDialog( dialog ); 661 QDialog::DialogCode result = (QDialog::DialogCode) QPEApplication::execDialog( dialog );
662#endif 662#endif
663 if (result == QDialog::Accepted) 663 if (result == QDialog::Accepted)
664 { 664 {
665 665
666 QString name = dialog->NameField->text(); 666 QString name = dialog->NameField->text();
667 if (cat == name) 667 if (cat == name)
668 { 668 {
669 QMessageBox::critical( 0, tr("ZSafe"), 669 QMessageBox::critical( 0, tr("ZSafe"),
670 tr("Entry name must be different\nfrom the category name.") ); 670 tr("Entry name must be different\nfrom the category name.") );
671 goto retype; // it's not a good programming style :-) 671 goto retype; // it's not a good programming style :-)
672 } 672 }
673 673
674 modified = true; 674 modified = true;
675 // add the new item 675 // add the new item
676 QListViewItem *i = new ShadedListItem (0, selectedItem); 676 QListViewItem *i = new ShadedListItem (0, selectedItem);
677 i->setOpen (TRUE); 677 i->setOpen (TRUE);
678 678
679 i->setText (0, tr (name)); 679 i->setText (0, tr (name));
680 QString user = dialog->UsernameField->text(); 680 QString user = dialog->UsernameField->text();
681 i->setText (1, tr (user)); 681 i->setText (1, tr (user));
682 QString pwd = dialog->PasswordField->text(); 682 QString pwd = dialog->PasswordField->text();
683 i->setText (2, tr (pwd)); 683 i->setText (2, tr (pwd));
684 QString comment = dialog->CommentField->text(); 684 QString comment = dialog->CommentField->text();
685 comment.replace (QRegExp("\n"), "<br>"); 685 comment.replace (QRegExp("\n"), "<br>");
686 i->setText (3, tr (comment)); 686 i->setText (3, tr (comment));
687 QString f5 = dialog->Field5->text(); 687 QString f5 = dialog->Field5->text();
688 i->setText (4, tr (f5)); 688 i->setText (4, tr (f5));
689 QString f6 = dialog->Field6->text(); 689 QString f6 = dialog->Field6->text();
690 i->setText (5, tr (f6)); 690 i->setText (5, tr (f6));
691 } 691 }
692 692
693 delete dialog; 693 delete dialog;
694 } 694 }
695} 695}
696 696
697void ZSafe::findPwd() 697void ZSafe::findPwd()
698{ 698{
699 699
700 // open the 'Search' dialog 700 // open the 'Search' dialog
701 SearchDialog *dialog = new SearchDialog(this, tr("Search"), TRUE); 701 SearchDialog *dialog = new SearchDialog(this, tr("Search"), TRUE);
702 702
703 if (lastSearchedName) 703 if (lastSearchedName)
704 dialog->NameField->setText(lastSearchedName); 704 dialog->NameField->setText(lastSearchedName);
705 else 705 else
706 dialog->NameField->setText(""); 706 dialog->NameField->setText("");
707 if (lastSearchedUsername) 707 if (lastSearchedUsername)
708 dialog->UsernameField->setText(lastSearchedUsername); 708 dialog->UsernameField->setText(lastSearchedUsername);
709 else 709 else
710 dialog->UsernameField->setText(""); 710 dialog->UsernameField->setText("");
711 if (lastSearchedComment) 711 if (lastSearchedComment)
712 dialog->CommentField->setText(lastSearchedComment); 712 dialog->CommentField->setText(lastSearchedComment);
713 else 713 else
714 dialog->CommentField->setText(""); 714 dialog->CommentField->setText("");
715 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); 715 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec();
716 716
717 QString name; 717 QString name;
718 QString username; 718 QString username;
719 QString comment; 719 QString comment;
720 if (result == QDialog::Accepted) 720 if (result == QDialog::Accepted)
721 { 721 {
722 name = dialog->NameField->text(); 722 name = dialog->NameField->text();
723 username = dialog->UsernameField->text(); 723 username = dialog->UsernameField->text();
724 comment = dialog->CommentField->text(); 724 comment = dialog->CommentField->text();
725 } 725 }
726 else 726 else
727 { 727 {
728 delete dialog; 728 delete dialog;
729 return; 729 return;
730 } 730 }
731 731
732 if (!name.isEmpty() && name != lastSearchedName || 732 if (!name.isEmpty() && name != lastSearchedName ||
733 lastSearchedName.isEmpty() && !name.isEmpty()) 733 lastSearchedName.isEmpty() && !name.isEmpty())
734 { 734 {
735 // set search at the beginning if a new name is given 735 // set search at the beginning if a new name is given
736 lastSearchedCategory = NULL; 736 lastSearchedCategory = NULL;
737 lastSearchedItem = NULL; 737 lastSearchedItem = NULL;
738 } 738 }
739 lastSearchedName = name; 739 lastSearchedName = name;
740 if (!username.isEmpty() && username != lastSearchedUsername || 740 if (!username.isEmpty() && username != lastSearchedUsername ||
741 lastSearchedUsername.isEmpty() && !username.isEmpty()) 741 lastSearchedUsername.isEmpty() && !username.isEmpty())
742 { 742 {
743 // set search at the beginning if a new name is given 743 // set search at the beginning if a new name is given
744 lastSearchedCategory = NULL; 744 lastSearchedCategory = NULL;
745 lastSearchedItem = NULL; 745 lastSearchedItem = NULL;
746 } 746 }
747 lastSearchedUsername = username; 747 lastSearchedUsername = username;
748 if (!comment.isEmpty() && comment != lastSearchedComment || 748 if (!comment.isEmpty() && comment != lastSearchedComment ||
749 lastSearchedComment.isEmpty() && !comment.isEmpty()) 749 lastSearchedComment.isEmpty() && !comment.isEmpty())
750 { 750 {
751 // set search at the beginning if a new name is given 751 // set search at the beginning if a new name is given
752 lastSearchedCategory = NULL; 752 lastSearchedCategory = NULL;
753 lastSearchedItem = NULL; 753 lastSearchedItem = NULL;
754 } 754 }
755 lastSearchedComment = comment; 755 lastSearchedComment = comment;
756 756
757 ListView->clearSelection(); 757 ListView->clearSelection();
758 758
759 bool found=FALSE; 759 bool found=FALSE;
760 // step through all categories 760 // step through all categories
761 QListViewItem *i; 761 QListViewItem *i;
762 if (lastSearchedCategory) 762 if (lastSearchedCategory)
763 i = lastSearchedCategory; 763 i = lastSearchedCategory;
764 else 764 else
765 i = ListView->firstChild(); 765 i = ListView->firstChild();
766 for (; 766 for (;
767 i != NULL; 767 i != NULL;
768 i = i->nextSibling()) 768 i = i->nextSibling())
769 { 769 {
770 i->setSelected(FALSE); 770 i->setSelected(FALSE);
771 771
772 // step through all subitems 772 // step through all subitems
773 QListViewItem *si; 773 QListViewItem *si;
774 if (lastSearchedItem) 774 if (lastSearchedItem)
775 si = lastSearchedItem; 775 si = lastSearchedItem;
776 else 776 else
777 si = i->firstChild(); 777 si = i->firstChild();
778 // for (si = i->firstChild(); 778 // for (si = i->firstChild();
779 for (; 779 for (;
780 si != NULL; 780 si != NULL;
781 si = si->nextSibling()) 781 si = si->nextSibling())
782 { 782 {
783 if (si->isSelected()) 783 if (si->isSelected())
784 si->setSelected(FALSE); 784 si->setSelected(FALSE);
785 // ListView->repaintItem(si); 785 // ListView->repaintItem(si);
786 786
787 bool n=TRUE; 787 bool n=TRUE;
788 bool u=TRUE; 788 bool u=TRUE;
789 bool c=TRUE; 789 bool c=TRUE;
790 if (!name.isEmpty()) 790 if (!name.isEmpty())
791 n = (si->text(0)).contains (name, FALSE); 791 n = (si->text(0)).contains (name, FALSE);
792 if (!username.isEmpty()) 792 if (!username.isEmpty())
793 u = (si->text(1)).contains (username, FALSE); 793 u = (si->text(1)).contains (username, FALSE);
794 if (!comment.isEmpty()) 794 if (!comment.isEmpty())
795 c = (si->text(3)).contains (comment, FALSE); 795 c = (si->text(3)).contains (comment, FALSE);
796 796
797 if ((n && u && c ) && !found) 797 if ((n && u && c ) && !found)
798 { 798 {
799 selectedItem = si; 799 selectedItem = si;
800 si->setSelected(TRUE); 800 si->setSelected(TRUE);
801 ListView->setCurrentItem(si); 801 ListView->setCurrentItem(si);
802 ListView->ensureItemVisible(si); 802 ListView->ensureItemVisible(si);
803 ListView->triggerUpdate(); 803 ListView->triggerUpdate();
804 804
805 lastSearchedCategory = i; 805 lastSearchedCategory = i;
806 // set to the next item 806 // set to the next item
807 lastSearchedItem = si->nextSibling(); 807 lastSearchedItem = si->nextSibling();
808 if (!lastSearchedItem) 808 if (!lastSearchedItem)
809 { 809 {
810 // no next item within category -> set next category 810 // no next item within category -> set next category
811 lastSearchedCategory = i->nextSibling(); 811 lastSearchedCategory = i->nextSibling();
812 if (!lastSearchedCategory) 812 if (!lastSearchedCategory)
813 lastSearchedItem = NULL; // END 813 lastSearchedItem = NULL; // END
814 } 814 }
815 815
816 found = TRUE; 816 found = TRUE;
817 delete dialog; 817 delete dialog;
818 update(); 818 update();
819 return; 819 return;
820 } 820 }
821 } 821 }
822 lastSearchedCategory = i->nextSibling(); 822 lastSearchedCategory = i->nextSibling();
823 lastSearchedItem = NULL; 823 lastSearchedItem = NULL;
824 } 824 }
825 lastSearchedCategory = NULL; 825 lastSearchedCategory = NULL;
826 lastSearchedItem = NULL; 826 lastSearchedItem = NULL;
827 delete dialog; 827 delete dialog;
828 update(); 828 update();
829 QMessageBox::information( this, tr("ZSafe"), 829 QMessageBox::information( this, tr("ZSafe"),
830 tr("Entry not found"), tr("&OK"), 0); 830 tr("Entry not found"), tr("&OK"), 0);
831 831
832} 832}
833 833
834QString ZSafe::getFieldLabel (QListViewItem *_item, QString field, QString def) 834QString ZSafe::getFieldLabel (QListViewItem *_item, QString field, QString def)
835{ 835{
836 QString category; 836 QString category;
837 if (_item) 837 if (_item)
838 { 838 {
839 if (isCategory(_item)) 839 if (isCategory(_item))
840 { 840 {
841 category = _item->text(0); 841 category = _item->text(0);
842 } 842 }
843 else 843 else
844 { 844 {
845 QListViewItem *cat = _item->parent(); 845 QListViewItem *cat = _item->parent();
846 category = cat->text(0); 846 category = cat->text(0);
847 } 847 }
848 } 848 }
849 else 849 else
850 { 850 {
851 return def; 851 return def;
852 } 852 }
853 853
854 QString app_key = APP_KEY; 854 QString app_key = APP_KEY;
855 855
856 conf->setGroup( "fieldDefs" ); 856 conf->setGroup( "fieldDefs" );
857 QString label = conf->readEntry(app_key+category+"-field"+field,def); 857 QString label = conf->readEntry(app_key+category+"-field"+field,def);
858 conf->setGroup ("zsafe"); 858 conf->setGroup ("zsafe");
859 return label; 859 return label;
860} 860}
861 861
862QString ZSafe::getFieldLabel (QString category, QString field, QString def) 862QString ZSafe::getFieldLabel (QString category, QString field, QString def)
863{ 863{
864 QString app_key = APP_KEY; 864 QString app_key = APP_KEY;
865// #ifndef Q_WS_WIN 865// #ifndef Q_WS_WIN
866 conf->setGroup( "fieldDefs" ); 866 conf->setGroup( "fieldDefs" );
867 QString label = conf->readEntry(app_key+category+"-field"+field, 867 QString label = conf->readEntry(app_key+category+"-field"+field,
868 def); 868 def);
869// #else 869// #else
870 // QString label(def); 870 // QString label(def);
871// #endif 871// #endif
872 conf->setGroup ("zsafe"); 872 conf->setGroup ("zsafe");
873 return label; 873 return label;
874} 874}
875 875
876void ZSafe::showInfo( QListViewItem *_item) 876void ZSafe::showInfo( QListViewItem *_item)
877{ 877{
878 if (!_item) 878 if (!_item)
879 return; 879 return;
880 if (selectedItem != NULL) 880 if (selectedItem != NULL)
881 selectedItem->setSelected(FALSE); 881 selectedItem->setSelected(FALSE);
882 882
883 selectedItem = _item; 883 selectedItem = _item;
884 selectedItem->setSelected(TRUE); 884 selectedItem->setSelected(TRUE);
885 885
886 if (!isCategory(_item)) 886 if (!isCategory(_item))
887 { 887 {
888/* 888/*
889 QString label=selectedItem->text(0); 889 QString label=selectedItem->text(0);
890 label+="\n"; 890 label+="\n";
891 label+=selectedItem->text(1); 891 label+=selectedItem->text(1);
892 label+="\n"; 892 label+="\n";
893 label+=selectedItem->text(2); 893 label+=selectedItem->text(2);
894 label+="\n"; 894 label+="\n";
895 label+=selectedItem->text(3); 895 label+=selectedItem->text(3);
896*/ 896*/
897 897
898 QString text; 898 QString text;
899 QString entry; 899 QString entry;
900 900
901 text = "<html><body><div align=""center""><u><b>"; 901 text = "<html><body><div align=""center""><u><b>";
902 text += selectedItem->text(0); 902 text += selectedItem->text(0);
903 text += "</b></u><br></div><br>"; 903 text += "</b></u><br></div><br>";
904 904
905 entry = selectedItem->text(1); 905 entry = selectedItem->text(1);
906 if (!entry.isEmpty() && entry.compare(" ")) 906 if (!entry.isEmpty() && entry.compare(" "))
907 { 907 {
908 text += "<u><b>"; 908 text += "<u><b>";
909 text += getFieldLabel (selectedItem, "2", tr("Username")); 909 text += getFieldLabel (selectedItem, "2", tr("Username"));
910 text += ":<br></b></u><blockquote>"; 910 text += ":<br></b></u><blockquote>";
911 text += entry; 911 text += entry;
912 text += "</blockquote>"; 912 text += "</blockquote>";
913 // text += "<br>"; 913 // text += "<br>";
914 } 914 }
915 915
916 entry = selectedItem->text(2); 916 entry = selectedItem->text(2);
917 if (!entry.isEmpty() && entry.compare(" ")) 917 if (!entry.isEmpty() && entry.compare(" "))
918 { 918 {
919 text += "<u><b>"; 919 text += "<u><b>";
920 text += getFieldLabel (selectedItem, "3", tr("Password")); 920 text += getFieldLabel (selectedItem, "3", tr("Password"));
921 text += ":<br> </b></u><blockquote>"; 921 text += ":<br> </b></u><blockquote>";
922 text += entry; 922 text += entry;
923 text += "</blockquote>"; 923 text += "</blockquote>";
924 // text += "<br>"; 924 // text += "<br>";
925 } 925 }
926 926
927 entry = selectedItem->text(4); 927 entry = selectedItem->text(4);
928 if (!entry.isEmpty() && entry.compare(" ")) 928 if (!entry.isEmpty() && entry.compare(" "))
929 { 929 {
930 text += "<u><b>"; 930 text += "<u><b>";
931 text += getFieldLabel (selectedItem, "5", tr("Field 4")); 931 text += getFieldLabel (selectedItem, "5", tr("Field 4"));
932 text += ":<br> </b></u><blockquote>"; 932 text += ":<br> </b></u><blockquote>";
933 text += entry; 933 text += entry;
934 text += "</blockquote>"; 934 text += "</blockquote>";
935 // text += "<br>"; 935 // text += "<br>";
936 } 936 }
937 937
938 entry = selectedItem->text(5); 938 entry = selectedItem->text(5);
939 if (!entry.isEmpty() && entry.compare(" ")) 939 if (!entry.isEmpty() && entry.compare(" "))
940 { 940 {
941 text += "<u><b>"; 941 text += "<u><b>";
942 text += getFieldLabel (selectedItem, "6", tr("Field 5")); 942 text += getFieldLabel (selectedItem, "6", tr("Field 5"));
943 text += ":<br> </b></u><blockquote>"; 943 text += ":<br> </b></u><blockquote>";
944 text += entry; 944 text += entry;
945 text += "</blockquote>"; 945 text += "</blockquote>";
946 // text += "<br>"; 946 // text += "<br>";
947 } 947 }
948 948
949 entry = selectedItem->text(3); 949 entry = selectedItem->text(3);
950 if (!entry.isEmpty() && entry.compare(" ")) 950 if (!entry.isEmpty() && entry.compare(" "))
951 { 951 {
952 text += "<u><b>"; 952 text += "<u><b>";
953 text += getFieldLabel (selectedItem, "4", tr("Comment")); 953 text += getFieldLabel (selectedItem, "4", tr("Comment"));
954 text += ":<br> </b></u>"; 954 text += ":<br> </b></u>";
955 QString comment = selectedItem->text(3); 955 QString comment = selectedItem->text(3);
956 comment.replace (QRegExp("\n"), "<br>"); 956 comment.replace (QRegExp("\n"), "<br>");
957 text += comment; 957 text += comment;
958 // text += "<br>"; 958 // text += "<br>";
959 } 959 }
960 960
961 text += "</body></html>"; 961 text += "</body></html>";
962 962
963 infoForm->InfoText->setText(text); 963 infoForm->InfoText->setText(text);
964// infoForm->hide(); 964// infoForm->hide();
965#ifdef Q_WS_QWS 965#ifdef Q_WS_QWS
966 QPEApplication::showDialog( infoForm ); 966 QPEApplication::showDialog( infoForm );
967#endif 967#endif
968 968
969 } 969 }
970} 970}
971 971
972void ZSafe::listViewSelected( QListViewItem *_item) 972void ZSafe::listViewSelected( QListViewItem *_item)
973{ 973{
974 if (!_item) 974 if (!_item)
975 return; 975 return;
976 if (selectedItem != NULL) 976 if (selectedItem != NULL)
977 selectedItem->setSelected(FALSE); 977 selectedItem->setSelected(FALSE);
978 978
979 selectedItem = _item; 979 selectedItem = _item;
980 980
981 // set the column text dependent on the selected item 981 // set the column text dependent on the selected item
982 ListView->setColumnText(0, getFieldLabel (selectedItem, "1", tr("Name"))); 982 ListView->setColumnText(0, getFieldLabel (selectedItem, "1", tr("Name")));
983 ListView->setColumnText(1, getFieldLabel (selectedItem, "2", tr("Field 2"))); 983 ListView->setColumnText(1, getFieldLabel (selectedItem, "2", tr("Field 2")));
984 ListView->setColumnText(2, getFieldLabel (selectedItem, "3", tr("Field 3"))); 984 ListView->setColumnText(2, getFieldLabel (selectedItem, "3", tr("Field 3")));
985 ListView->setColumnText(3, getFieldLabel (selectedItem, "4", tr("Comment"))); 985 ListView->setColumnText(3, getFieldLabel (selectedItem, "4", tr("Comment")));
986 ListView->setColumnText(4, getFieldLabel (selectedItem, "5", tr("Field 4"))); 986 ListView->setColumnText(4, getFieldLabel (selectedItem, "5", tr("Field 4")));
987 ListView->setColumnText(5, getFieldLabel (selectedItem, "6", tr("Field 5"))); 987 ListView->setColumnText(5, getFieldLabel (selectedItem, "6", tr("Field 5")));
988} 988}
989 989
990bool ZSafe::isCategory(QListViewItem *_item) 990bool ZSafe::isCategory(QListViewItem *_item)
991{ 991{
992 if (_item == NULL) 992 if (_item == NULL)
993 return FALSE; 993 return FALSE;
994 994
995 QString categoryName = _item->text (0); 995 QString categoryName = _item->text (0);
996 if (categories.find (categoryName)) 996 if (categories.find (categoryName))
997 return TRUE; 997 return TRUE;
998 else 998 else
999 return FALSE; 999 return FALSE;
1000} 1000}
1001 1001
1002void ZSafe::removeAsciiFile() 1002void ZSafe::removeAsciiFile()
1003{ 1003{
1004 // QString fn = filename + ".txt"; 1004 // QString fn = filename + ".txt";
1005 // open the file dialog 1005 // open the file dialog
1006 QMap<QString, QStringList> mimeTypes; 1006 QMap<QString, QStringList> mimeTypes;
1007 mimeTypes.insert(tr("All"), QStringList() ); 1007 mimeTypes.insert(tr("All"), QStringList() );
1008 mimeTypes.insert(tr("Text"), "text/*" ); 1008 mimeTypes.insert(tr("Text"), "text/*" );
1009 QString fn = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL, 1009 QString fn = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL,
1010 QDir::homeDirPath() + "/Documents/application/zsafe", 1010 QDir::homeDirPath() + "/Documents/application/zsafe",
1011 QString::null, 1011 QString::null,
1012 mimeTypes, 1012 mimeTypes,
1013 this, 1013 this,
1014 tr ("Remove text file")); 1014 tr ("Remove text file"));
1015 1015
1016 if (fn && fn.length() > 0 ) 1016 if (fn && fn.length() > 0 )
1017 { 1017 {
1018 QFile f( fn ); 1018 QFile f( fn );
1019 if ( !f.remove() ) 1019 if ( !f.remove() )
1020 { 1020 {
1021 QMessageBox::critical( 0, tr("ZSafe"), 1021 QMessageBox::critical( 0, tr("ZSafe"),
1022 tr("Could not remove text file.") ); 1022 tr("Could not remove text file.") );
1023 return; 1023 return;
1024 } 1024 }
1025 } 1025 }
1026} 1026}
1027 1027
1028void ZSafe::writeAllEntries() 1028void ZSafe::writeAllEntries()
1029{ 1029{
1030 if (filename.isEmpty()) 1030 if (filename.isEmpty())
1031 { 1031 {
1032 QMessageBox::critical( 0, tr("ZSafe"), 1032 QMessageBox::critical( 0, tr("ZSafe"),
1033 tr("No document defined.\nYou have to create a new document")); 1033 tr("No document defined.\nYou have to create a new document"));
1034 return; 1034 return;
1035 } 1035 }
1036 1036
1037 // open the file dialog 1037 // open the file dialog
1038 QString fn = zsaveDialog(); 1038 QString fn = zsaveDialog();
1039 // open the new document 1039 // open the new document
1040 if (fn && fn.length() > 0 ) 1040 if (fn && fn.length() > 0 )
1041 { 1041 {
1042 QFile f( fn ); 1042 QFile f( fn );
1043 if ( !f.open( IO_WriteOnly ) ) { 1043 if ( !f.open( IO_WriteOnly ) ) {
1044 QMessageBox::critical( 0, "ZSafe", 1044 QMessageBox::critical( 0, "ZSafe",
1045 QString("Could not export to text file.") ); 1045 QString("Could not export to text file.") );
1046 return; 1046 return;
1047 } 1047 }
1048 QTextStream t( &f ); 1048 QTextStream t( &f );
1049 1049
1050 QListViewItem *i; 1050 QListViewItem *i;
1051 // step through all categories 1051 // step through all categories
1052 for (i = ListView->firstChild(); 1052 for (i = ListView->firstChild();
1053 i != NULL; 1053 i != NULL;
1054 i = i->nextSibling()) 1054 i = i->nextSibling())
1055 { 1055 {
1056 // step through all subitems 1056 // step through all subitems
1057 QListViewItem *si; 1057 QListViewItem *si;
1058 for (si = i->firstChild(); 1058 for (si = i->firstChild();
1059 si != NULL; 1059 si != NULL;
1060 si = si->nextSibling()) 1060 si = si->nextSibling())
1061 { 1061 {
1062 QString oneEntry; 1062 QString oneEntry;
1063 oneEntry += "\""; 1063 oneEntry += "\"";
1064 oneEntry += i->text(0); 1064 oneEntry += i->text(0);
1065 oneEntry += "\";"; 1065 oneEntry += "\";";
1066 oneEntry += "\""; 1066 oneEntry += "\"";
1067 oneEntry += si->text(0); 1067 oneEntry += si->text(0);
1068 oneEntry += "\";"; 1068 oneEntry += "\";";
1069 oneEntry += "\""; 1069 oneEntry += "\"";
1070 oneEntry += si->text(1); 1070 oneEntry += si->text(1);
1071 oneEntry += "\";"; 1071 oneEntry += "\";";
1072 oneEntry += "\""; 1072 oneEntry += "\"";
1073 oneEntry += si->text(2); 1073 oneEntry += si->text(2);
1074 oneEntry += "\";"; 1074 oneEntry += "\";";
1075 oneEntry += "\""; 1075 oneEntry += "\"";
1076 QString comment = si->text(3); 1076 QString comment = si->text(3);
1077 comment.replace (QRegExp("\n"), "<br>"); 1077 comment.replace (QRegExp("\n"), "<br>");
1078 oneEntry += comment; 1078 oneEntry += comment;
1079 oneEntry += "\";"; 1079 oneEntry += "\";";
1080 oneEntry += "\""; 1080 oneEntry += "\"";
1081 oneEntry += si->text(4); 1081 oneEntry += si->text(4);
1082 oneEntry += "\";"; 1082 oneEntry += "\";";
1083 oneEntry += "\""; 1083 oneEntry += "\"";
1084 oneEntry += si->text(5); 1084 oneEntry += si->text(5);
1085 oneEntry += "\""; 1085 oneEntry += "\"";
1086 // owarn << oneEntry << oendl; 1086 // owarn << oneEntry << oendl;
1087 t << oneEntry << endl; 1087 t << oneEntry << endl;
1088 1088
1089 // owarn << si->text(0) << oendl; 1089 // owarn << si->text(0) << oendl;
1090 } 1090 }
1091 } 1091 }
1092 f.close(); 1092 f.close();
1093 } 1093 }
1094} 1094}
1095 1095
1096void ZSafe::readAllEntries() 1096void ZSafe::readAllEntries()
1097{ 1097{
1098 if (filename.isEmpty()) 1098 if (filename.isEmpty())
1099 { 1099 {
1100 QMessageBox::critical( 0, tr("ZSafe"), 1100 QMessageBox::critical( 0, tr("ZSafe"),
1101 tr("No document defined.\nYou have to create a new document")); 1101 tr("No document defined.\nYou have to create a new document"));
1102 return; 1102 return;
1103 } 1103 }
1104 1104
1105 // open the file dialog 1105 // open the file dialog
1106 QMap<QString, QStringList> mimeTypes; 1106 QMap<QString, QStringList> mimeTypes;
1107 mimeTypes.insert(tr("All"), QStringList() ); 1107 mimeTypes.insert(tr("All"), QStringList() );
1108 mimeTypes.insert(tr("Text"), "text/*" ); 1108 mimeTypes.insert(tr("Text"), "text/*" );
1109 QString fn = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL, 1109 QString fn = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL,
1110 QDir::homeDirPath() + "/Documents/application/zsafe", 1110 QDir::homeDirPath() + "/Documents/application/zsafe",
1111 QString::null, 1111 QString::null,
1112 mimeTypes, 1112 mimeTypes,
1113 this, 1113 this,
1114 tr ("Import text file")); 1114 tr ("Import text file"));
1115 1115
1116 if (fn && fn.length() > 0 ) 1116 if (fn && fn.length() > 0 )
1117 { 1117 {
1118 QFile f( fn ); 1118 QFile f( fn );
1119 if ( !f.open( IO_ReadOnly ) ) 1119 if ( !f.open( IO_ReadOnly ) )
1120 { 1120 {
1121 QMessageBox::critical( 0, "ZSafe", 1121 QMessageBox::critical( 0, "ZSafe",
1122 QString("Could not import text file.") ); 1122 QString("Could not import text file.") );
1123 return; 1123 return;
1124 } 1124 }
1125 1125
1126 modified = true; 1126 modified = true;
1127 1127
1128 // clear the password list 1128 // clear the password list
1129 selectedItem = NULL; 1129 selectedItem = NULL;
1130 QListViewItem *i; 1130 QListViewItem *i;
1131 // step through all categories 1131 // step through all categories
1132 for (i = ListView->firstChild(); 1132 for (i = ListView->firstChild();
1133 i != NULL; 1133 i != NULL;
1134 i = i->nextSibling()) 1134 i = i->nextSibling())
1135 { 1135 {
1136 // step through all subitems 1136 // step through all subitems
1137 QListViewItem *si; 1137 QListViewItem *si;
1138 for (si = i->firstChild(); 1138 for (si = i->firstChild();
1139 si != NULL; ) 1139 si != NULL; )
1140 // si = si->nextSibling()) 1140 // si = si->nextSibling())
1141 { 1141 {
1142 QListViewItem *_si = si; 1142 QListViewItem *_si = si;
1143 si = si->nextSibling(); 1143 si = si->nextSibling();
1144 i->takeItem(_si); // remove from view list 1144 i->takeItem(_si); // remove from view list
1145 if (_si) delete _si; 1145 if (_si) delete _si;
1146 } 1146 }
1147 } 1147 }
1148 1148
1149 QTextStream t(&f); 1149 QTextStream t(&f);
1150 while ( !t.eof() ) 1150 while ( !t.eof() )
1151 { 1151 {
1152 QString s = t.readLine(); 1152 QString s = t.readLine();
1153 s.replace (QRegExp("\";\""), "\"|\""); 1153 s.replace (QRegExp("\";\""), "\"|\"");
1154 // char buffer[1024]; 1154 // char buffer[1024];
1155 char buffer[s.length()+1]; 1155 char buffer[s.length()+1];
1156 1156
1157 1157
1158 /* modify QString -> QCString::utf8 */ 1158 /* modify QString -> QCString::utf8 */
1159 1159
1160 strcpy (buffer, s.utf8()); 1160 strcpy (buffer, s.utf8());
1161 1161
1162 QString name; 1162 QString name;
1163 QString user; 1163 QString user;
1164 QString password; 1164 QString password;
1165 QString comment; 1165 QString comment;
1166 QString field5=""; 1166 QString field5="";
1167 QString field6=""; 1167 QString field6="";
1168 1168
1169 // separete the entries 1169 // separete the entries
1170 char *i = strtok (buffer, "|"); 1170 char *i = strtok (buffer, "|");
1171 QString category(QString::fromUtf8(&i[1])); 1171 QString category(QString::fromUtf8(&i[1]));
1172 category.truncate(category.length() -1); 1172 category.truncate(category.length() -1);
1173 1173
1174 int idx=0; 1174 int idx=0;
1175 while ((i = strtok (NULL, "|")) != NULL) 1175 while ((i = strtok (NULL, "|")) != NULL)
1176 { 1176 {
1177 switch (idx) 1177 switch (idx)
1178 { 1178 {
1179 case 0: 1179 case 0:
1180 name = QString::fromUtf8(&i[1]); 1180 name = QString::fromUtf8(&i[1]);
1181 name.truncate(name.length() -1); 1181 name.truncate(name.length() -1);
1182 // name 1182 // name
1183 break; 1183 break;
1184 case 1: 1184 case 1:
1185 // user 1185 // user
1186 user = QString::fromUtf8(&i[1]); 1186 user = QString::fromUtf8(&i[1]);
1187 user.truncate(user.length() -1); 1187 user.truncate(user.length() -1);
1188 break; 1188 break;
1189 case 2: 1189 case 2:
1190 // password 1190 // password
1191 password = QString::fromUtf8(&i[1]); 1191 password = QString::fromUtf8(&i[1]);
1192 password.truncate(password.length() -1); 1192 password.truncate(password.length() -1);
1193 break; 1193 break;
1194 case 3: 1194 case 3:
1195 // comment 1195 // comment
1196 comment = QString::fromUtf8(&i[1]); 1196 comment = QString::fromUtf8(&i[1]);
1197 comment.truncate(comment.length() -1); 1197 comment.truncate(comment.length() -1);
1198 break; 1198 break;
1199 case 4: 1199 case 4:
1200 // field5 1200 // field5
1201 field5 = QString::fromUtf8(&i[1]); 1201 field5 = QString::fromUtf8(&i[1]);
1202 field5.truncate(field5.length() -1); 1202 field5.truncate(field5.length() -1);
1203 break; 1203 break;
1204 case 5: 1204 case 5:
1205 // field6 1205 // field6
1206 field6 = QString::fromUtf8(&i[1]); 1206 field6 = QString::fromUtf8(&i[1]);
1207 field6.truncate(field6.length() -1); 1207 field6.truncate(field6.length() -1);
1208 break; 1208 break;
1209 } 1209 }
1210 idx++; 1210 idx++;
1211 } 1211 }
1212 1212
1213 Category *cat= categories.find (category); 1213 Category *cat= categories.find (category);
1214 if (cat) 1214 if (cat)
1215 { 1215 {
1216 // use the existend item 1216 // use the existend item
1217 QListViewItem *catItem = cat->getListItem(); 1217 QListViewItem *catItem = cat->getListItem();
1218 if (catItem) 1218 if (catItem)
1219 { 1219 {
1220 QListViewItem * item = new ShadedListItem( 0, catItem ); 1220 QListViewItem * item = new ShadedListItem( 0, catItem );
1221 item->setText( 0, tr( name ) ); 1221 item->setText( 0, tr( name ) );
1222 item->setText( 1, tr( user ) ); 1222 item->setText( 1, tr( user ) );
1223 item->setText( 2, tr( password ) ); 1223 item->setText( 2, tr( password ) );
1224 item->setText( 3, tr( comment ) ); 1224 item->setText( 3, tr( comment ) );
1225 item->setText( 4, tr( field5 ) ); 1225 item->setText( 4, tr( field5 ) );
1226 item->setText( 5, tr( field6 ) ); 1226 item->setText( 5, tr( field6 ) );
1227 catItem->setOpen( TRUE ); 1227 catItem->setOpen( TRUE );
1228 } 1228 }
1229 } 1229 }
1230 else 1230 else
1231 { 1231 {
1232 QListViewItem *catI = new ShadedListItem( 1, ListView ); 1232 QListViewItem *catI = new ShadedListItem( 1, ListView );
1233 // create and insert a new item 1233 // create and insert a new item
1234 QListViewItem * item = new ShadedListItem( 0, catI ); 1234 QListViewItem * item = new ShadedListItem( 0, catI );
1235 item->setText( 0, tr( name ) ); 1235 item->setText( 0, tr( name ) );
1236 item->setText( 1, tr( user ) ); 1236 item->setText( 1, tr( user ) );
1237 item->setText( 2, tr( password ) ); 1237 item->setText( 2, tr( password ) );
1238 item->setText( 3, tr( comment ) ); 1238 item->setText( 3, tr( comment ) );
1239 item->setText( 4, tr( field5 ) ); 1239 item->setText( 4, tr( field5 ) );
1240 item->setText( 5, tr( field6 ) ); 1240 item->setText( 5, tr( field6 ) );
1241 1241
1242 catI->setOpen( TRUE ); 1242 catI->setOpen( TRUE );
1243 1243
1244 Category *c1 = new Category(); 1244 Category *c1 = new Category();
1245 c1->setCategoryName(category); 1245 c1->setCategoryName(category);
1246 1246
1247 QString icon; 1247 QString icon;
1248 QString fullIconPath; 1248 QString fullIconPath;
1249 QPixmap *pix; 1249 QPixmap *pix;
1250// #ifndef Q_WS_WIN 1250// #ifndef Q_WS_WIN
1251 icon = conf->readEntry(APP_KEY+category); 1251 icon = conf->readEntry(APP_KEY+category);
1252// #endif 1252// #endif
1253 bool isIconAv = false; 1253 bool isIconAv = false;
1254 if (!icon.isEmpty() && !icon.isNull()) 1254 if (!icon.isEmpty() && !icon.isNull())
1255 { 1255 {
1256 // build the full path 1256 // build the full path
1257 fullIconPath = iconPath + icon; 1257 fullIconPath = iconPath + icon;
1258 pix = new QPixmap (fullIconPath); 1258 pix = new QPixmap (fullIconPath);
1259 if (!pix->isNull()) 1259 if (!pix->isNull())
1260 { 1260 {
1261 QImage img = pix->convertToImage(); 1261 QImage img = pix->convertToImage();
1262 pix->convertFromImage(img.smoothScale(14,14)); 1262 pix->convertFromImage(img.smoothScale(14,14));
1263 c1->setIconName (icon); 1263 c1->setIconName (icon);
1264 c1->setIcon (*pix); 1264 c1->setIcon (*pix);
1265 isIconAv = true; 1265 isIconAv = true;
1266 } 1266 }
1267 } 1267 }
1268 if (!isIconAv) 1268 if (!isIconAv)
1269 { 1269 {
1270 c1->setIcon (*getPredefinedIcon(category)); 1270 c1->setIcon (*getPredefinedIcon(category));
1271 } 1271 }
1272 c1->setListItem (catI); 1272 c1->setListItem (catI);
1273 c1->initListItem(); 1273 c1->initListItem();
1274 categories.insert (c1->getCategoryName(), c1); 1274 categories.insert (c1->getCategoryName(), c1);
1275 } 1275 }
1276 1276
1277 } 1277 }
1278 f.close(); 1278 f.close();
1279 1279
1280 } 1280 }
1281 else 1281 else
1282 { 1282 {
1283 } 1283 }
1284 1284
1285} 1285}
1286 1286
1287#ifdef UNUSED 1287#ifdef UNUSED
1288void ZSafe::writeAllEntries() 1288void ZSafe::writeAllEntries()
1289{ 1289{
1290 if (filename.isEmpty()) 1290 if (filename.isEmpty())
1291 { 1291 {
1292 QMessageBox::critical( 0, tr("ZSafe"), 1292 QMessageBox::critical( 0, tr("ZSafe"),
1293 tr("<P>No document defined. You have to create a new document</P>")); 1293 tr("<P>No document defined. You have to create a new document</P>"));
1294 return; 1294 return;
1295 } 1295 }
1296 1296
1297 // open the file for writing 1297 // open the file for writing
1298 QString fn = filename + ".txt"; 1298 QString fn = filename + ".txt";
1299 QFile f( fn ); 1299 QFile f( fn );
1300 if ( !f.open( IO_WriteOnly ) ) { 1300 if ( !f.open( IO_WriteOnly ) ) {
1301 QMessageBox::critical( 0, tr("ZSafe"), 1301 QMessageBox::critical( 0, tr("ZSafe"),
1302 tr("Could not export to text file.") ); 1302 tr("Could not export to text file.") );
1303 return; 1303 return;
1304 } 1304 }
1305 QTextStream t( &f ); 1305 QTextStream t( &f );
1306 1306
1307 QListViewItem *i; 1307 QListViewItem *i;
1308 // step through all categories 1308 // step through all categories
1309 for (i = ListView->firstChild(); 1309 for (i = ListView->firstChild();
1310 i != NULL; 1310 i != NULL;
1311 i = i->nextSibling()) 1311 i = i->nextSibling())
1312 { 1312 {
1313 // step through all subitems 1313 // step through all subitems
1314 QListViewItem *si; 1314 QListViewItem *si;
1315 for (si = i->firstChild(); 1315 for (si = i->firstChild();
1316 si != NULL; 1316 si != NULL;
1317 si = si->nextSibling()) 1317 si = si->nextSibling())
1318 { 1318 {
1319 QString oneEntry; 1319 QString oneEntry;
1320 oneEntry += "\""; 1320 oneEntry += "\"";
1321 oneEntry += i->text(0); 1321 oneEntry += i->text(0);
1322 oneEntry += "\";"; 1322 oneEntry += "\";";
1323 oneEntry += "\""; 1323 oneEntry += "\"";
1324 oneEntry += si->text(0); 1324 oneEntry += si->text(0);
1325 oneEntry += "\";"; 1325 oneEntry += "\";";
1326 oneEntry += "\""; 1326 oneEntry += "\"";
1327 oneEntry += si->text(1); 1327 oneEntry += si->text(1);
1328 oneEntry += "\";"; 1328 oneEntry += "\";";
1329 oneEntry += "\""; 1329 oneEntry += "\"";
1330 oneEntry += si->text(2); 1330 oneEntry += si->text(2);
1331 oneEntry += "\";"; 1331 oneEntry += "\";";
1332 oneEntry += "\""; 1332 oneEntry += "\"";
1333 // oneEntry += si->text(3); 1333 // oneEntry += si->text(3);
1334 QString comment = si->text(3); 1334 QString comment = si->text(3);
1335 comment.replace (QRegExp("\n"), "<br>"); 1335 comment.replace (QRegExp("\n"), "<br>");
1336 oneEntry += comment; 1336 oneEntry += comment;
1337 oneEntry += "\""; 1337 oneEntry += "\"";
1338 // owarn << oneEntry << oendl; 1338 // owarn << oneEntry << oendl;
1339 t << oneEntry << endl; 1339 t << oneEntry << endl;
1340 1340
1341 // owarn << si->text(0) << oendl; 1341 // owarn << si->text(0) << oendl;
1342 } 1342 }
1343 } 1343 }
1344 f.close(); 1344 f.close();
1345} 1345}
1346 1346
1347void ZSafe::readAllEntries() 1347void ZSafe::readAllEntries()
1348{ 1348{
1349 QString fn = filename + ".txt"; 1349 QString fn = filename + ".txt";
1350 QFile f( fn ); 1350 QFile f( fn );
1351 if ( !f.open( IO_ReadOnly ) ) 1351 if ( !f.open( IO_ReadOnly ) )
1352 { 1352 {
1353 QMessageBox::critical( 0, tr("ZSafe"), 1353 QMessageBox::critical( 0, tr("ZSafe"),
1354 tr("Could not import text file.") ); 1354 tr("Could not import text file.") );
1355 return; 1355 return;
1356 } 1356 }
1357 1357
1358 modified = true; 1358 modified = true;
1359 1359
1360 // clear the password list 1360 // clear the password list
1361 selectedItem = NULL; 1361 selectedItem = NULL;
1362 QListViewItem *i; 1362 QListViewItem *i;
1363 // step through all categories 1363 // step through all categories
1364 for (i = ListView->firstChild(); 1364 for (i = ListView->firstChild();
1365 i != NULL; 1365 i != NULL;
1366 i = i->nextSibling()) 1366 i = i->nextSibling())
1367 { 1367 {
1368 // step through all subitems 1368 // step through all subitems
1369 QListViewItem *si; 1369 QListViewItem *si;
1370 for (si = i->firstChild(); 1370 for (si = i->firstChild();
1371 si != NULL; ) 1371 si != NULL; )
1372 // si = si->nextSibling()) 1372 // si = si->nextSibling())
1373 { 1373 {
1374 QListViewItem *_si = si; 1374 QListViewItem *_si = si;
1375 si = si->nextSibling(); 1375 si = si->nextSibling();
1376 i->takeItem(_si); // remove from view list 1376 i->takeItem(_si); // remove from view list
1377 if (_si) delete _si; 1377 if (_si) delete _si;
1378 } 1378 }
1379 } 1379 }
1380 1380
1381 QTextStream t(&f); 1381 QTextStream t(&f);
1382 while ( !t.eof() ) 1382 while ( !t.eof() )
1383 { 1383 {
1384 QString s = t.readLine(); 1384 QString s = t.readLine();
1385 s.replace (QRegExp("\";\""), "\"|\""); 1385 s.replace (QRegExp("\";\""), "\"|\"");
1386 // char buffer[1024]; 1386 // char buffer[1024];
1387 int len=s.length()+1; 1387 int len=s.length()+1;
1388 char buffer[len]; 1388 char buffer[len];
1389 strcpy (buffer, s); 1389 strcpy (buffer, s);
1390 1390
1391 QString name; 1391 QString name;
1392 QString user; 1392 QString user;
1393 QString password; 1393 QString password;
1394 QString comment; 1394 QString comment;
1395 1395
1396 // separete the entries 1396 // separete the entries
1397 char *i = strtok (buffer, "|"); 1397 char *i = strtok (buffer, "|");
1398 QString category(&i[1]); 1398 QString category(&i[1]);
1399 category.truncate(category.length() -1); 1399 category.truncate(category.length() -1);
1400 1400
1401 int idx=0; 1401 int idx=0;
1402 while (i = strtok (NULL, "|")) 1402 while (i = strtok (NULL, "|"))
1403 { 1403 {
1404 switch (idx) 1404 switch (idx)
1405 { 1405 {
1406 case 0: 1406 case 0:
1407 name = &i[1]; 1407 name = &i[1];
1408 name.truncate(name.length() -1); 1408 name.truncate(name.length() -1);
1409 // name 1409 // name
1410 break; 1410 break;
1411 case 1: 1411 case 1:
1412 // user 1412 // user
1413 user = &i[1]; 1413 user = &i[1];
1414 user.truncate(user.length() -1); 1414 user.truncate(user.length() -1);
1415 break; 1415 break;
1416 case 2: 1416 case 2:
1417 // password 1417 // password
1418 password = &i[1]; 1418 password = &i[1];
1419 password.truncate(password.length() -1); 1419 password.truncate(password.length() -1);
1420 break; 1420 break;
1421 case 3: 1421 case 3:
1422 // comment 1422 // comment
1423 comment = &i[1]; 1423 comment = &i[1];
1424 comment.truncate(comment.length() -1); 1424 comment.truncate(comment.length() -1);
1425 break; 1425 break;
1426 } 1426 }
1427 idx++; 1427 idx++;
1428 } 1428 }
1429 1429
1430 Category *cat= categories.find (category); 1430 Category *cat= categories.find (category);
1431 if (cat) 1431 if (cat)
1432 { 1432 {
1433 // use the existend item 1433 // use the existend item
1434 QListViewItem *catItem = cat->getListItem(); 1434 QListViewItem *catItem = cat->getListItem();
1435 if (catItem) 1435 if (catItem)
1436 { 1436 {
1437 QListViewItem * item = new ShadedListItem( 0, catItem ); 1437 QListViewItem * item = new ShadedListItem( 0, catItem );
1438 item->setText( 0, tr( name ) ); 1438 item->setText( 0, tr( name ) );
1439 item->setText( 1, tr( user ) ); 1439 item->setText( 1, tr( user ) );
1440 item->setText( 2, tr( password ) ); 1440 item->setText( 2, tr( password ) );
1441 item->setText( 3, tr( comment ) ); 1441 item->setText( 3, tr( comment ) );
1442 1442
1443 catItem->setOpen( TRUE ); 1443 catItem->setOpen( TRUE );
1444 } 1444 }
1445 } 1445 }
1446 else 1446 else
1447 { 1447 {
1448 QListViewItem *catI = new ShadedListItem( 1, ListView ); 1448 QListViewItem *catI = new ShadedListItem( 1, ListView );
1449 // create and insert a new item 1449 // create and insert a new item
1450 QListViewItem * item = new ShadedListItem( 0, catI ); 1450 QListViewItem * item = new ShadedListItem( 0, catI );
1451 item->setText( 0, tr( name ) ); 1451 item->setText( 0, tr( name ) );
1452 item->setText( 1, tr( user ) ); 1452 item->setText( 1, tr( user ) );
1453 item->setText( 2, tr( password ) ); 1453 item->setText( 2, tr( password ) );
1454 item->setText( 3, tr( comment ) ); 1454 item->setText( 3, tr( comment ) );
1455 1455
1456 catI->setOpen( TRUE ); 1456 catI->setOpen( TRUE );
1457 1457
1458 Category *c1 = new Category(); 1458 Category *c1 = new Category();
1459 c1->setCategoryName(category); 1459 c1->setCategoryName(category);
1460 1460
1461 QString icon; 1461 QString icon;
1462 QString fullIconPath; 1462 QString fullIconPath;
1463 QPixmap *pix; 1463 QPixmap *pix;
1464// #ifndef Q_WS_WIN 1464// #ifndef Q_WS_WIN
1465 icon = conf->readEntry(APP_KEY+category); 1465 icon = conf->readEntry(APP_KEY+category);
1466// #endif 1466// #endif
1467 bool isIconAv = false; 1467 bool isIconAv = false;
1468 if (!icon.isEmpty() && !icon.isNull()) 1468 if (!icon.isEmpty() && !icon.isNull())
1469 { 1469 {
1470 // build the full path 1470 // build the full path
1471 fullIconPath = iconPath + icon; 1471 fullIconPath = iconPath + icon;
1472 pix = new QPixmap (fullIconPath); 1472 pix = new QPixmap (fullIconPath);
1473 if (!pix->isNull()) 1473 if (!pix->isNull())
1474 { 1474 {
1475 QImage img = pix->convertToImage(); 1475 QImage img = pix->convertToImage();
1476 pix->convertFromImage(img.smoothScale(14,14)); 1476 pix->convertFromImage(img.smoothScale(14,14));
1477 c1->setIconName (icon); 1477 c1->setIconName (icon);
1478 c1->setIcon (*pix); 1478 c1->setIcon (*pix);
1479 isIconAv = true; 1479 isIconAv = true;
1480 } 1480 }
1481 } 1481 }
1482 if (!isIconAv) 1482 if (!isIconAv)
1483 { 1483 {
1484 c1->setIcon (*getPredefinedIcon(category)); 1484 c1->setIcon (*getPredefinedIcon(category));
1485 } 1485 }
1486 c1->setListItem (catI); 1486 c1->setListItem (catI);
1487 c1->initListItem(); 1487 c1->initListItem();
1488 categories.insert (c1->getCategoryName(), c1); 1488 categories.insert (c1->getCategoryName(), c1);
1489 } 1489 }
1490 1490
1491 } 1491 }
1492 f.close(); 1492 f.close();
1493 1493
1494} 1494}
1495#endif // UNUSED 1495#endif // UNUSED
1496 1496
1497void ZSafe::resume(int) 1497void ZSafe::resume(int)
1498{ 1498{
1499 // hide the main window 1499 // hide the main window
1500 1500
1501 if ( !showpwd ) 1501 if ( !showpwd )
1502 { 1502 {
1503 infoForm->hide(); 1503 infoForm->hide();
1504 // open zsafe again 1504 // open zsafe again
1505 m_password = ""; 1505 m_password = "";
1506 selectedItem = NULL; 1506 selectedItem = NULL;
1507 1507
1508 // clear the password list 1508 // clear the password list
1509 QListViewItem *i; 1509 QListViewItem *i;
1510 // step through all categories 1510 // step through all categories
1511 for (i = ListView->firstChild(); 1511 for (i = ListView->firstChild();
1512 i != NULL; 1512 i != NULL;
1513 i = i->nextSibling()) 1513 i = i->nextSibling())
1514 { 1514 {
1515 // step through all subitems 1515 // step through all subitems
1516 QListViewItem *si; 1516 QListViewItem *si;
1517 for (si = i->firstChild(); 1517 for (si = i->firstChild();
1518 si != NULL; ) 1518 si != NULL; )
1519 { 1519 {
1520 QListViewItem *_si = si; 1520 QListViewItem *_si = si;
1521 si = si->nextSibling(); 1521 si = si->nextSibling();
1522 i->takeItem(_si); // remove from view list 1522 i->takeItem(_si); // remove from view list
1523 if (_si) delete _si; 1523 if (_si) delete _si;
1524 } 1524 }
1525 } 1525 }
1526 1526
1527 // ask for password and read again 1527 // ask for password and read again
1528 openDocument(filename); 1528 openDocument(filename);
1529 } 1529 }
1530} 1530}
1531 1531
1532//--------------------------------------------- 1532//---------------------------------------------
1533 1533
1534 1534
1535bool ZSafe::openDocument(const char* _filename, const char* ) 1535bool ZSafe::openDocument(const char* _filename, const char* )
1536{ 1536{
1537 QString name= _filename; 1537 QString name= _filename;
1538 qWarning("openDocument "+name); 1538 qWarning("openDocument "+name);
1539 int retval; 1539 int retval;
1540 char* entry[FIELD_SIZE]; 1540 char* entry[FIELD_SIZE];
1541// #ifndef Q_WS_WIN 1541// #ifndef Q_WS_WIN
1542 int validationFlag = conf->readNumEntry(APP_KEY+"valzsafe", 1); 1542 int validationFlag = conf->readNumEntry(APP_KEY+"valzsafe", 1);
1543// #else 1543// #else
1544 // int validationFlag = 1; 1544 // int validationFlag = 1;
1545// #endif 1545// #endif
1546 1546
1547 int pwdOk = 0; 1547 int pwdOk = 0;
1548 int numberOfTries = 3; 1548 int numberOfTries = 3;
1549 for (int i=0; i < numberOfTries; i++) 1549 for (int i=0; i < numberOfTries; i++)
1550 { 1550 {
1551 QFile f(_filename); 1551 QFile f(_filename);
1552 if (f.exists()) 1552 if (f.exists())
1553 { 1553 {
1554 // ask with a dialog for the password 1554 // ask with a dialog for the password
1555 if (m_password.isEmpty()) 1555 if (m_password.isEmpty())
1556 getDocPassword(tr("Enter Password")); 1556 getDocPassword(tr("Enter Password"));
1557 if (m_password.isEmpty() && validationFlag == 0) 1557 if (m_password.isEmpty() && validationFlag == 0)
1558 { 1558 {
1559 QMessageBox::critical( 0, tr("ZSafe"), 1559 QMessageBox::critical( 0, tr("ZSafe"),
1560 tr("Wrong password.\n\nZSafe will now exit.") ); 1560 tr("Wrong password.\n\nZSafe will now exit.") );
1561 exitZs (1); 1561 exitZs (1);
1562 } 1562 }
1563 1563
1564 retval = loadInit(_filename, m_password); 1564 retval = loadInit(_filename, m_password);
1565 if (retval != PWERR_GOOD) 1565 if (retval != PWERR_GOOD)
1566 { 1566 {
1567 return false; 1567 return false;
1568 } 1568 }
1569 } 1569 }
1570 else 1570 else
1571 { 1571 {
1572 this->setCaption(tr("ZSafe")); 1572 this->setCaption(tr("ZSafe"));
1573 filename = ""; 1573 filename = "";
1574 switch( QMessageBox::warning( this, tr("ZSafe"), 1574 switch( QMessageBox::warning( this, tr("ZSafe"),
1575 tr("<P>You must create a new document first. Ok to create?</P>"), 1575 tr("<P>You must create a new document first. Ok to create?</P>"),
1576 tr("&Yes"), tr("&No."), 1576 tr("&Yes"), tr("&No."),
1577 0 1577 0
1578 ) ) 1578 ) )
1579 { 1579 {
1580 case 1: // No 1580 case 1: // No
1581 return false; 1581 return false;
1582 break; 1582 break;
1583 case 0: // Yes 1583 case 0: // Yes
1584 newDocument(); 1584 newDocument();
1585 return false; 1585 return false;
1586 break; 1586 break;
1587 } 1587 }
1588 1588
1589 } 1589 }
1590 1590
1591 1591
1592 // load the validation entry 1592 // load the validation entry
1593 if (validationFlag == 0) 1593 if (validationFlag == 0)
1594 { 1594 {
1595 pwdOk = 1; 1595 pwdOk = 1;
1596 break; 1596 break;
1597 } 1597 }
1598 1598
1599 retval = loadEntry(entry); 1599 retval = loadEntry(entry);
1600 if (retval == 1 && 1600 if (retval == 1 &&
1601 !strcmp (entry[0], "ZSAFECATEGORY") && 1601 !strcmp (entry[0], "ZSAFECATEGORY") &&
1602 !strcmp (entry[1], "name") && 1602 !strcmp (entry[1], "name") &&
1603 !strcmp (entry[2], "username") && 1603 !strcmp (entry[2], "username") &&
1604 !strcmp (entry[3], "password") && 1604 !strcmp (entry[3], "password") &&
1605 !strcmp (entry[4], "comment") ) 1605 !strcmp (entry[4], "comment") )
1606 { 1606 {
1607 for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); 1607 for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]);
1608 pwdOk = 1; 1608 pwdOk = 1;
1609 break; 1609 break;
1610 } 1610 }
1611 else 1611 else
1612 // for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); 1612 // for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]);
1613 fclose (fd); 1613 fclose (fd);
1614 m_password = ""; 1614 m_password = "";
1615 1615
1616 if (i < numberOfTries - 1) 1616 if (i < numberOfTries - 1)
1617 { 1617 {
1618 switch( QMessageBox::warning( this, tr("ZSafe"), 1618 switch( QMessageBox::warning( this, tr("ZSafe"),
1619 tr("Wrong password.\nEnter again?"), 1619 tr("Wrong password.\nEnter again?"),
1620 tr("&Yes"), tr("&No."), 1620 tr("&Yes"), tr("&No."),
1621 0 1621 0
1622 ) ) 1622 ) )
1623 { 1623 {
1624 case 1: // No 1624 case 1: // No
1625 exitZs (1); 1625 exitZs (1);
1626 break; 1626 break;
1627 case 0: // Yes 1627 case 0: // Yes
1628 continue; 1628 continue;
1629 } 1629 }
1630 } 1630 }
1631 } 1631 }
1632 if (pwdOk == 0) 1632 if (pwdOk == 0)
1633 { 1633 {
1634 // unset the document entry 1634 // unset the document entry
1635 conf->writeEntry(APP_KEY+"document", "INVALIDPWD"); 1635 conf->writeEntry(APP_KEY+"document", "INVALIDPWD");
1636 if (conf) 1636 if (conf)
1637 delete conf; 1637 delete conf;
1638 1638
1639 exitZs (1); 1639 exitZs (1);
1640 } 1640 }
1641 1641
1642 1642
1643 retval = loadEntry(entry); 1643 retval = loadEntry(entry);
1644 1644
1645 int numberOfEntries=0; 1645 int numberOfEntries=0;
1646 while (retval == 1) { 1646 while (retval == 1) {
1647 1647
1648 QString category( QString::fromUtf8(entry[0]) ); 1648 QString category( QString::fromUtf8(entry[0]) );
1649 QString name( QString::fromUtf8(entry[1]) ); 1649 QString name( QString::fromUtf8(entry[1]) );
1650 QString user( QString::fromUtf8(entry[2]) ); 1650 QString user( QString::fromUtf8(entry[2]) );
1651 QString password( QString::fromUtf8(entry[3]) ); 1651 QString password( QString::fromUtf8(entry[3]) );
1652 QString comment( QString::fromUtf8(entry[4]) ); 1652 QString comment( QString::fromUtf8(entry[4]) );
1653 QString field5( QString::fromUtf8(entry[5]) ); 1653 QString field5( QString::fromUtf8(entry[5]) );
1654 QString field6( QString::fromUtf8(entry[6]) ); 1654 QString field6( QString::fromUtf8(entry[6]) );
1655 // add the subitems to the categories 1655 // add the subitems to the categories
1656 1656
1657 Category *cat= categories.find (category); 1657 Category *cat= categories.find (category);
1658 if (cat) 1658 if (cat)
1659 { 1659 {
1660 // use the existend item 1660 // use the existend item
1661 QListViewItem *catItem = cat->getListItem(); 1661 QListViewItem *catItem = cat->getListItem();
1662 if (catItem) 1662 if (catItem)
1663 { 1663 {
1664 QListViewItem * item = new ShadedListItem( 0, catItem ); 1664 QListViewItem * item = new ShadedListItem( 0, catItem );
1665 item->setText( 0, tr( name ) ); 1665 item->setText( 0, tr( name ) );
1666 item->setText( 1, tr( user ) ); 1666 item->setText( 1, tr( user ) );
1667 item->setText( 2, tr( password ) ); 1667 item->setText( 2, tr( password ) );
1668 item->setText( 3, tr( comment ) ); 1668 item->setText( 3, tr( comment ) );
1669 item->setText( 4, tr( field5 ) ); 1669 item->setText( 4, tr( field5 ) );
1670 item->setText( 5, tr( field6 ) ); 1670 item->setText( 5, tr( field6 ) );
1671 1671
1672 if (expandTree) 1672 if (expandTree)
1673 catItem->setOpen( TRUE ); 1673 catItem->setOpen( TRUE );
1674 numberOfEntries++; 1674 numberOfEntries++;
1675 } 1675 }
1676 } 1676 }
1677 else 1677 else
1678 { 1678 {
1679 QListViewItem *catI = new ShadedListItem( 1, ListView ); 1679 QListViewItem *catI = new ShadedListItem( 1, ListView );
1680 // create and insert a new item 1680 // create and insert a new item
1681 QListViewItem * item = new ShadedListItem( 0, catI ); 1681 QListViewItem * item = new ShadedListItem( 0, catI );
1682 1682
1683 item->setText( 0, tr( name ) ); 1683 item->setText( 0, tr( name ) );
1684 item->setText( 1, tr( user ) ); 1684 item->setText( 1, tr( user ) );
1685 item->setText( 2, tr( password ) ); 1685 item->setText( 2, tr( password ) );
1686 item->setText( 3, tr( comment ) ); 1686 item->setText( 3, tr( comment ) );
1687 item->setText( 4, tr( field5 ) ); 1687 item->setText( 4, tr( field5 ) );
1688 item->setText( 5, tr( field6 ) ); 1688 item->setText( 5, tr( field6 ) );
1689 1689
1690 if (expandTree) 1690 if (expandTree)
1691 catI->setOpen( TRUE ); 1691 catI->setOpen( TRUE );
1692 1692
1693 Category *c1 = new Category(); 1693 Category *c1 = new Category();
1694 c1->setCategoryName(category); 1694 c1->setCategoryName(category);
1695 1695
1696 QString icon; 1696 QString icon;
1697 QString fullIconPath; 1697 QString fullIconPath;
1698 QPixmap *pix; 1698 QPixmap *pix;
1699// #ifndef Q_WS_WIN 1699// #ifndef Q_WS_WIN
1700 icon = conf->readEntry(APP_KEY+category); 1700 icon = conf->readEntry(APP_KEY+category);
1701// #endif 1701// #endif
1702 bool isIconAv = false; 1702 bool isIconAv = false;
1703 if (!icon.isEmpty() && !icon.isNull()) 1703 if (!icon.isEmpty() && !icon.isNull())
1704 { 1704 {
1705 // build the full path 1705 // build the full path
1706 fullIconPath = iconPath + icon; 1706 fullIconPath = iconPath + icon;
1707 pix = new QPixmap (fullIconPath); 1707 pix = new QPixmap (fullIconPath);
1708 if (!pix->isNull()) 1708 if (!pix->isNull())
1709 { 1709 {
1710 QImage img = pix->convertToImage(); 1710 QImage img = pix->convertToImage();
1711 pix->convertFromImage(img.smoothScale(14,14)); 1711 pix->convertFromImage(img.smoothScale(14,14));
1712 c1->setIconName (icon); 1712 c1->setIconName (icon);
1713 c1->setIcon (*pix); 1713 c1->setIcon (*pix);
1714 isIconAv = true; 1714 isIconAv = true;
1715 } 1715 }
1716 } 1716 }
1717 if (!isIconAv) 1717 if (!isIconAv)
1718 { 1718 {
1719 c1->setIcon (*getPredefinedIcon(category)); 1719 c1->setIcon (*getPredefinedIcon(category));
1720 } 1720 }
1721 1721
1722 c1->setListItem (catI); 1722 c1->setListItem (catI);
1723 c1->initListItem(); 1723 c1->initListItem();
1724 categories.insert (c1->getCategoryName(), c1); 1724 categories.insert (c1->getCategoryName(), c1);
1725 numberOfEntries++; 1725 numberOfEntries++;
1726 } 1726 }
1727 1727
1728 for (int count = 0; count < FIELD_SIZE; count++) { 1728 for (int count = 0; count < FIELD_SIZE; count++) {
1729 free(entry[count]); 1729 free(entry[count]);
1730 } 1730 }
1731 retval = loadEntry(entry); 1731 retval = loadEntry(entry);
1732 if (retval == 2) { 1732 if (retval == 2) {
1733 // m_parent->slotStatusHelpMsg("Last entry loaded"); 1733 // m_parent->slotStatusHelpMsg("Last entry loaded");
1734 } 1734 }
1735 } // end while 1735 } // end while
1736 1736
1737 if (numberOfEntries == 0) 1737 if (numberOfEntries == 0)
1738 { 1738 {
1739 1739
1740 switch( QMessageBox::warning( this, tr("ZSafe"), 1740 switch( QMessageBox::warning( this, tr("ZSafe"),
1741 tr("Empty document or\nwrong password.\nContinue?"), 1741 tr("Empty document or\nwrong password.\nContinue?"),
1742 tr("&No"), tr("&Yes."), 1742 tr("&No"), tr("&Yes."),
1743 0 1743 0
1744 ) ) { 1744 ) ) {
1745 case 0: // No 1745 case 0: // No
1746 retval = loadFinalize(); 1746 retval = loadFinalize();
1747 exitZs (1); 1747 exitZs (1);
1748 break; 1748 break;
1749 case 1: // Yes 1749 case 1: // Yes
1750 break; 1750 break;
1751 } 1751 }
1752 } 1752 }
1753 1753
1754 retval = loadFinalize(); 1754 retval = loadFinalize();
1755 1755
1756 return true; 1756 return true;
1757} 1757}
1758 1758
1759int ZSafe::loadInit(const char* _filename, const char *password) 1759int ZSafe::loadInit(const char* _filename, const char *password)
1760{ 1760{
1761 unsigned int j = 0; 1761 unsigned int j = 0;
1762 unsigned int keylength=0; 1762 unsigned int keylength=0;
1763 int count=0, count2=0, count3=0; 1763 int count=0, count2=0, count3=0;
1764 unsigned char charbuf[8]; 1764 unsigned char charbuf[8];
1765 unsigned short ciphertext[4]; 1765 unsigned short ciphertext[4];
1766 char key[128]; 1766 char key[128];
1767 Krc2* krc2 = new Krc2(); 1767 Krc2* krc2 = new Krc2();
1768 1768
1769 fd = fopen (_filename, "rb"); 1769 fd = fopen (_filename, "rb");
1770 1770
1771 QFileInfo f (_filename); 1771 QFileInfo f (_filename);
1772 load_buffer_length = f.size(); 1772 load_buffer_length = f.size();
1773 load_buffer_length = ((load_buffer_length / 1024)+1) * 1024 * 2; 1773 load_buffer_length = ((load_buffer_length / 1024)+1) * 1024 * 2;
1774 1774
1775 if (fd == NULL) 1775 if (fd == NULL) {
1776 delete krc2;
1776 return PWERR_OPEN; 1777 return PWERR_OPEN;
1778 }
1777 1779
1778 buffer = (char *)malloc(load_buffer_length); 1780 buffer = (char *)malloc(load_buffer_length);
1779 for (j = 0; password[j] != '\0'; j++) { 1781 for (j = 0; password[j] != '\0'; j++) {
1780 key[j] = password[j]; 1782 key[j] = password[j];
1781 } 1783 }
1782 keylength = j; 1784 keylength = j;
1783 krc2->rc2_expandkey (key, keylength, 128); 1785 krc2->rc2_expandkey (key, keylength, 128);
1784 1786
1785#ifndef Q_WS_WIN 1787#ifndef Q_WS_WIN
1786 size = read(fileno (fd), (unsigned char *) (charbuf + count), 8); 1788 size = read(fileno (fd), (unsigned char *) (charbuf + count), 8);
1787#else 1789#else
1788 size = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); 1790 size = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd);
1789#endif 1791#endif
1790 1792
1791 if (size < 8) 1793 if (size < 8) {
1794 delete krc2;
1792 return PWERR_DATA; 1795 return PWERR_DATA;
1796 }
1793 1797
1794 for (count = 0; count < 4; count++) { 1798 for (count = 0; count < 4; count++) {
1795 count2 = count << 1; 1799 count2 = count << 1;
1796 iv[count] = charbuf[count2] << 8; 1800 iv[count] = charbuf[count2] << 8;
1797 iv[count] += charbuf[count2 + 1]; 1801 iv[count] += charbuf[count2 + 1];
1798 } 1802 }
1799 1803
1800 size = 0; 1804 size = 0;
1801 bufferIndex = 0; 1805 bufferIndex = 0;
1802#ifndef Q_WS_WIN 1806#ifndef Q_WS_WIN
1803 while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) { 1807 while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) {
1804 while (count < 8) { 1808 while (count < 8) {
1805 count2 = read (fileno (fd), (unsigned char *) (charbuf + count), 8); 1809 count2 = read (fileno (fd), (unsigned char *) (charbuf + count), 8);
1806#else 1810#else
1807 while ((count = fread ((unsigned char *) (charbuf), sizeof(unsigned char), 8, fd)) > 0) { 1811 while ((count = fread ((unsigned char *) (charbuf), sizeof(unsigned char), 8, fd)) > 0) {
1808 while (count < 8) { 1812 while (count < 8) {
1809 count2 = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); 1813 count2 = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd);
1810#endif 1814#endif
1811 if (count2 == 0) { 1815 if (count2 == 0) {
1816 delete krc2;
1812 return PWERR_DATA; 1817 return PWERR_DATA;
1813 } 1818 }
1814 count += count2; 1819 count += count2;
1815 } /* while (count < 8) */ 1820 } /* while (count < 8) */
1816 1821
1817 size += 8; 1822 size += 8;
1818 for (count2 = 0; count2 < 8; count2 += 2) { 1823 for (count2 = 0; count2 < 8; count2 += 2) {
1819 count3 = count2 >> 1; 1824 count3 = count2 >> 1;
1820 ciphertext[count3] = charbuf[count2] << 8; 1825 ciphertext[count3] = charbuf[count2] << 8;
1821 ciphertext[count3] += charbuf[count2 + 1]; 1826 ciphertext[count3] += charbuf[count2 + 1];
1822 1827
1823 plaintext[count3] = ciphertext[count3] ^ iv[count3]; 1828 plaintext[count3] = ciphertext[count3] ^ iv[count3];
1824 iv[count3] = plaintext[count3]; 1829 iv[count3] = plaintext[count3];
1825 } /* for (count2) */ 1830 } /* for (count2) */
1826 1831
1827 krc2->rc2_decrypt (plaintext); 1832 krc2->rc2_decrypt (plaintext);
1828 memcpy ((unsigned char *) (buffer + bufferIndex), plaintext, 8); 1833 memcpy ((unsigned char *) (buffer + bufferIndex), plaintext, 8);
1829 bufferIndex += 8; 1834 bufferIndex += 8;
1830 buffer[bufferIndex + 1] = '\0'; 1835 buffer[bufferIndex + 1] = '\0';
1831 } /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */ 1836 } /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */
1837 delete krc2;
1832 size -= buffer[size - 1]; 1838 size -= buffer[size - 1];
1833 lastcount = 0; 1839 lastcount = 0;
1834 1840
1835 /* This will point to the starting index */ 1841 /* This will point to the starting index */
1836 bufferIndex = 0; 1842 bufferIndex = 0;
1837 return PWERR_GOOD; 1843 return PWERR_GOOD;
1838} 1844}
1839 1845
1840int ZSafe::loadEntry(char *entry[FIELD_SIZE]) 1846int ZSafe::loadEntry(char *entry[FIELD_SIZE])
1841{ 1847{
1842 /* Strip off PKCS 5 padding 1848 /* Strip off PKCS 5 padding
1843 * Should check to make sure it's good here 1849 * Should check to make sure it's good here
1844 */ 1850 */
1845 int count, count1=0; 1851 int count, count1=0;
1846 1852
1847 for (count = lastcount; count < size; count++) { 1853 for (count = lastcount; count < size; count++) {
1848 if ((unsigned char) (buffer[count]) == 255) { 1854 if ((unsigned char) (buffer[count]) == 255) {
1849 if (buffer[bufferIndex] == '\0') { 1855 if (buffer[bufferIndex] == '\0') {
1850 bufferIndex++; 1856 bufferIndex++;
1851 } 1857 }
1852 entry[count1] = (char *) malloc (count - bufferIndex + 1); 1858 entry[count1] = (char *) malloc (count - bufferIndex + 1);
1853 memcpy (entry[count1], (unsigned char *) (buffer + bufferIndex), count - bufferIndex); 1859 memcpy (entry[count1], (unsigned char *) (buffer + bufferIndex), count - bufferIndex);
1854 entry[count1][count - bufferIndex] = '\0'; 1860 entry[count1][count - bufferIndex] = '\0';
1855 count++; 1861 count++;
1856 bufferIndex = count; 1862 bufferIndex = count;
1857 count1++; 1863 count1++;
1858 if (count1 == FIELD_SIZE) { 1864 if (count1 == FIELD_SIZE) {
1859 lastcount = count; 1865 lastcount = count;
1860 return 1; 1866 return 1;
1861 } 1867 }
1862 } /* if ((unsigned char) (buffer[count]) == 255) */ 1868 } /* if ((unsigned char) (buffer[count]) == 255) */
1863 } /* for (count = 0; count < size; count++) */ 1869 } /* for (count = 0; count < size; count++) */
1864 1870
1865 return 2; 1871 return 2;
1866} 1872}
1867 1873
1868int ZSafe::loadFinalize(void) 1874int ZSafe::loadFinalize(void)
1869{ 1875{
1870 fclose (fd); 1876 fclose (fd);
1871 if (buffer) free(buffer); 1877 if (buffer) free(buffer);
1872 return PWERR_GOOD; 1878 return PWERR_GOOD;
1873} 1879}
1874 1880
1875bool ZSafe::saveDocument(const char* _filename, 1881bool ZSafe::saveDocument(const char* _filename,
1876 bool withPwd, 1882 bool withPwd,
1877 const char* ) 1883 const char* )
1878{ 1884{
1879 if (filename.isEmpty()) 1885 if (filename.isEmpty())
1880 { 1886 {
1881 QMessageBox::critical( 0, tr("ZSafe"), 1887 QMessageBox::critical( 0, tr("ZSafe"),
1882 tr("No document defined.\nYou have to create a new document")); 1888 tr("No document defined.\nYou have to create a new document"));
1883 return false; 1889 return false;
1884 } 1890 }
1885 1891
1886 // if (m_password.isEmpty()) 1892 // if (m_password.isEmpty())
1887 // withPwd = true; // the document must be saved with a valid password 1893 // withPwd = true; // the document must be saved with a valid password
1888 if (withPwd) 1894 if (withPwd)
1889 { 1895 {
1890 bool pwdOk = FALSE; 1896 bool pwdOk = FALSE;
1891 while (!pwdOk) 1897 while (!pwdOk)
1892 { 1898 {
1893 getDocPassword(tr("Enter Password")); 1899 getDocPassword(tr("Enter Password"));
1894 if (m_password.isEmpty()) 1900 if (m_password.isEmpty())
1895 { 1901 {
1896 1902
1897 QMessageBox::critical( 0, tr("ZSafe"), 1903 QMessageBox::critical( 0, tr("ZSafe"),
1898 tr("Password is empty.\nPlease enter again.")); 1904 tr("Password is empty.\nPlease enter again."));
1899 continue; 1905 continue;
1900 } 1906 }
1901 1907
1902 QString firstPasswd = m_password; 1908 QString firstPasswd = m_password;
1903 1909
1904 getDocPassword(tr("Reenter Password")); 1910 getDocPassword(tr("Reenter Password"));
1905 if (m_password.isEmpty()) 1911 if (m_password.isEmpty())
1906 { 1912 {
1907 QMessageBox::critical( 0, tr("ZSafe"), 1913 QMessageBox::critical( 0, tr("ZSafe"),
1908 tr("Password is empty.\nPlease enter again.")); 1914 tr("Password is empty.\nPlease enter again."));
1909 continue; 1915 continue;
1910 } 1916 }
1911 if (firstPasswd != m_password) 1917 if (firstPasswd != m_password)
1912 { 1918 {
1913 1919
1914 QMessageBox::critical( 0, tr("ZSafe"), 1920 QMessageBox::critical( 0, tr("ZSafe"),
1915 tr("Passwords must be identical.\nPlease enter again.")); 1921 tr("Passwords must be identical.\nPlease enter again."));
1916 continue; 1922 continue;
1917 } 1923 }
1918 pwdOk = TRUE; 1924 pwdOk = TRUE;
1919 modified = false; 1925 modified = false;
1920 } 1926 }
1921 } 1927 }
1922 else if (modified) 1928 else if (modified)
1923 { 1929 {
1924 QString fns(_filename); 1930 QString fns(_filename);
1925 fns = fns.right (fns.length() - fns.findRev ('/') - 1); 1931 fns = fns.right (fns.length() - fns.findRev ('/') - 1);
1926 switch( QMessageBox::information( this, tr("ZSafe"), 1932 switch( QMessageBox::information( this, tr("ZSafe"),
1927 tr("Do you want to save ") + fns + tr("\nbefore continuing?"), 1933 tr("Do you want to save ") + fns + tr("\nbefore continuing?"),
1928 tr("&Save"), 1934 tr("&Save"),
1929 tr("&Don't Save"), 1935 tr("&Don't Save"),
1930 0 // Enter == button 0 1936 0 // Enter == button 0
1931 ) ) 1937 ) )
1932 { // Escape == button 2 1938 { // Escape == button 2
1933 case 0: // Save clicked, Alt-S or Enter pressed. 1939 case 0: // Save clicked, Alt-S or Enter pressed.
1934 modified = false; 1940 modified = false;
1935 break; 1941 break;
1936 case 1: // Don't Save clicked or Alt-D pressed 1942 case 1: // Don't Save clicked or Alt-D pressed
1937 modified = false; 1943 modified = false;
1938 return true; 1944 return true;
1939 } 1945 }
1940 } 1946 }
1941 modified = false; 1947 modified = false;
1942 1948
1943 if (m_password.isEmpty()) 1949 if (m_password.isEmpty())
1944 return false; 1950 return false;
1945 1951
1946 int retval = saveInit(_filename, m_password); 1952 int retval = saveInit(_filename, m_password);
1947 // int retval = saveInit(_filename, "test"); 1953 // int retval = saveInit(_filename, "test");
1948 if (retval != PWERR_GOOD) { 1954 if (retval != PWERR_GOOD) {
1949 return false; 1955 return false;
1950 } 1956 }
1951 1957
1952 char* entry[FIELD_SIZE]; 1958 char* entry[FIELD_SIZE];
1953 1959
1954 // save the validation entry 1960 // save the validation entry
1955 { 1961 {
1956 int i=0; 1962 int i=0;
1957 entry[i] = (char*)malloc(strlen("ZSAFECATEGORY")+1); 1963 entry[i] = (char*)malloc(strlen("ZSAFECATEGORY")+1);
1958 strcpy(entry[i++], "ZSAFECATEGORY"); 1964 strcpy(entry[i++], "ZSAFECATEGORY");
1959 entry[i] = (char*)malloc(strlen("name")+1); 1965 entry[i] = (char*)malloc(strlen("name")+1);
1960 strcpy(entry[i++], "name"); 1966 strcpy(entry[i++], "name");
1961 entry[i] = (char*)malloc(strlen("username")+1); 1967 entry[i] = (char*)malloc(strlen("username")+1);
1962 strcpy(entry[i++], "username"); 1968 strcpy(entry[i++], "username");
1963 entry[i] = (char*)malloc(strlen("password")+1); 1969 entry[i] = (char*)malloc(strlen("password")+1);
1964 strcpy(entry[i++], "password"); 1970 strcpy(entry[i++], "password");
1965 entry[i] = (char*)malloc(strlen("comment")+1); 1971 entry[i] = (char*)malloc(strlen("comment")+1);
1966 strcpy(entry[i++], "comment"); 1972 strcpy(entry[i++], "comment");
1967 1973
1968 entry[i] = (char*)malloc(strlen("field5")+1); 1974 entry[i] = (char*)malloc(strlen("field5")+1);
1969 strcpy(entry[i++], "field5"); 1975 strcpy(entry[i++], "field5");
1970 entry[i] = (char*)malloc(strlen("field6")+1); 1976 entry[i] = (char*)malloc(strlen("field6")+1);
1971 strcpy(entry[i++], "field6"); 1977 strcpy(entry[i++], "field6");
1972 1978
1973 retval = saveEntry(entry); 1979 retval = saveEntry(entry);
1974 for (int z=0; z<i; z++) free(entry[z]); 1980 for (int z=0; z<i; z++) free(entry[z]);
1975 if (retval == PWERR_DATA) { 1981 if (retval == PWERR_DATA) {
1976#ifndef NO_OPIE 1982#ifndef NO_OPIE
1977 owarn << "1: Error writing file, contents not saved" << oendl; 1983 owarn << "1: Error writing file, contents not saved" << oendl;
1978#else 1984#else
1979 qWarning("1: Error writing file, contents not saved"); 1985 qWarning("1: Error writing file, contents not saved");
1980#endif 1986#endif
1981 saveFinalize(); 1987 saveFinalize();
1982 return false; 1988 return false;
1983 } 1989 }
1984// #ifndef Q_WS_WIN 1990// #ifndef Q_WS_WIN
1985 conf->writeEntry(APP_KEY+"valzsafe", 1); 1991 conf->writeEntry(APP_KEY+"valzsafe", 1);
1986// #endif 1992// #endif
1987 saveConf(); 1993 saveConf();
1988 } 1994 }
1989 1995
1990 QListViewItem *i; 1996 QListViewItem *i;
1991 // step through all categories 1997 // step through all categories
1992 for (i = ListView->firstChild(); 1998 for (i = ListView->firstChild();
1993 i != NULL; 1999 i != NULL;
1994 i = i->nextSibling()) 2000 i = i->nextSibling())
1995 { 2001 {
1996 // step through all subitems 2002 // step through all subitems
1997 QListViewItem *si; 2003 QListViewItem *si;
1998 for (si = i->firstChild(); 2004 for (si = i->firstChild();
1999 si != NULL; 2005 si != NULL;
2000 si = si->nextSibling()) 2006 si = si->nextSibling())
2001 { 2007 {
2002 int j=0; 2008 int j=0;
2003 entry[j] = (char*)malloc(strlen(i->text(0).utf8())+1); 2009 entry[j] = (char*)malloc(strlen(i->text(0).utf8())+1);
2004 strcpy(entry[j++], i->text(0).utf8()); 2010 strcpy(entry[j++], i->text(0).utf8());
2005 entry[j] = (char*)malloc(strlen(si->text(0).utf8())+1); 2011 entry[j] = (char*)malloc(strlen(si->text(0).utf8())+1);
2006 strcpy(entry[j++], si->text(0).utf8()); 2012 strcpy(entry[j++], si->text(0).utf8());
2007 entry[j] = (char*)malloc(strlen(si->text(1).utf8())+1); 2013 entry[j] = (char*)malloc(strlen(si->text(1).utf8())+1);
2008 strcpy(entry[j++], si->text(1).utf8()); 2014 strcpy(entry[j++], si->text(1).utf8());
2009 entry[j] = (char*)malloc(strlen(si->text(2).utf8())+1); 2015 entry[j] = (char*)malloc(strlen(si->text(2).utf8())+1);
2010 strcpy(entry[j++], si->text(2).utf8()); 2016 strcpy(entry[j++], si->text(2).utf8());
2011 entry[j] = (char*)malloc(strlen(si->text(3).utf8())+1); 2017 entry[j] = (char*)malloc(strlen(si->text(3).utf8())+1);
2012 strcpy(entry[j++], si->text(3).utf8()); 2018 strcpy(entry[j++], si->text(3).utf8());
2013 entry[j] = (char*)malloc(strlen(si->text(4).utf8())+1); 2019 entry[j] = (char*)malloc(strlen(si->text(4).utf8())+1);
2014 strcpy(entry[j++], si->text(4).utf8()); 2020 strcpy(entry[j++], si->text(4).utf8());
2015 entry[j] = (char*)malloc(strlen(si->text(5).utf8())+1); 2021 entry[j] = (char*)malloc(strlen(si->text(5).utf8())+1);
2016 strcpy(entry[j++], si->text(5).utf8()); 2022 strcpy(entry[j++], si->text(5).utf8());
2017 2023
2018 retval = saveEntry(entry); 2024 retval = saveEntry(entry);
2019 for (int z=0; z<j; z++) 2025 for (int z=0; z<j; z++)
2020 { 2026 {
2021 free(entry[z]); 2027 free(entry[z]);
2022 } 2028 }
2023 if (retval == PWERR_DATA) { 2029 if (retval == PWERR_DATA) {
2024#ifndef NO_OPIE 2030#ifndef NO_OPIE
2025 owarn << "1: Error writing file, contents not saved" << oendl; 2031 owarn << "1: Error writing file, contents not saved" << oendl;
2026#else 2032#else
2027 qWarning("1: Error writing file, contents not saved"); 2033 qWarning("1: Error writing file, contents not saved");
2028#endif 2034#endif
2029 saveFinalize(); 2035 saveFinalize();
2030 return false; 2036 return false;
2031 } 2037 }
2032 2038
2033 } 2039 }
2034 } 2040 }
2035 2041
2036 if (saveFinalize() == PWERR_DATA) { 2042 if (saveFinalize() == PWERR_DATA) {
2037#ifndef NO_OPIE 2043#ifndef NO_OPIE
2038 owarn << "2: Error writing file, contents not saved" << oendl; 2044 owarn << "2: Error writing file, contents not saved" << oendl;
2039#else 2045#else
2040 qWarning("2: Error writing file, contents not saved"); 2046 qWarning("2: Error writing file, contents not saved");
2041#endif 2047#endif
2042 return false; 2048 return false;
2043 } else { 2049 } else {
2044#ifndef DESKTOP 2050#ifndef DESKTOP
2045 Global::statusMessage (tr("Password file saved.")); 2051 Global::statusMessage (tr("Password file saved."));
2046#endif 2052#endif
2047 modified = false; 2053 modified = false;
2048 return true; 2054 return true;
2049 } 2055 }
2050} 2056}
2051 2057
2052PasswordForm *newPwdDialog; 2058PasswordForm *newPwdDialog;
2053bool newPwdDialogResult = false; 2059bool newPwdDialogResult = false;
2054void ZSafe::setPasswordDialogDone() 2060void ZSafe::setPasswordDialogDone()
2055{ 2061{
2056 newPwdDialogResult = true; 2062 newPwdDialogResult = true;
2057 newPwdDialog->close(); 2063 newPwdDialog->close();
2058} 2064}
2059 2065
2060void ZSafe::getDocPassword(QString title) 2066void ZSafe::getDocPassword(QString title)
2061{ 2067{
2062 // open the 'Password' dialog 2068 // open the 'Password' dialog
2063 PasswordForm *dialog = new PasswordForm(this, title, TRUE); 2069 PasswordForm *dialog = new PasswordForm(this, title, TRUE);
2064 newPwdDialog = dialog; 2070 newPwdDialog = dialog;
2065 newPwdDialogResult = false; 2071 newPwdDialogResult = false;
2066 2072
2067// QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon ); 2073// QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon );
2068 // dialog->setIcon( image0); 2074 // dialog->setIcon( image0);
2069 2075
2070 connect( dialog->PasswordField, SIGNAL( returnPressed() ), 2076 connect( dialog->PasswordField, SIGNAL( returnPressed() ),
2071 this, SLOT( setPasswordDialogDone() ) ); 2077 this, SLOT( setPasswordDialogDone() ) );
2072 2078
2073 // CS: !!! 2079 // CS: !!!
2074 // int pos = filename.findRev ('/'); 2080 // int pos = filename.findRev ('/');
2075 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 2081 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
2076 dialog->setCaption(ti); 2082 dialog->setCaption(ti);
2077 // dialog->setCaption(title); 2083 // dialog->setCaption(title);
2078 2084
2079 dialog->PasswordField->setFocus(); 2085 dialog->PasswordField->setFocus();
2080 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); 2086 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec();
2081 2087
2082 QString password; 2088 QString password;
2083 if (result == QDialog::Accepted || newPwdDialogResult) 2089 if (result == QDialog::Accepted || newPwdDialogResult)
2084 { 2090 {
2085 m_password = dialog->PasswordField->text(); 2091 m_password = dialog->PasswordField->text();
2086 } 2092 }
2087 else 2093 else
2088 { 2094 {
2089 exitZs (1); 2095 exitZs (1);
2090 } 2096 }
2091} 2097}
2092 2098
2093int ZSafe::saveInit(const char *_filename, const char *password) 2099int ZSafe::saveInit(const char *_filename, const char *password)
2094{ 2100{
2095 char key[128]; 2101 char key[128];
2096 unsigned int j = 0; 2102 unsigned int j = 0;
2097 unsigned int keylength; 2103 unsigned int keylength;
2098 // int val; 2104 // int val;
2099 int count2; 2105 int count2;
2100 Krc2* krc2 = new Krc2(); 2106 Krc2* krc2 = new Krc2();
2101 2107
2102 /* first we should check the permissions of the filename */ 2108 QFileInfo f (_filename);
2103/* 2109 save_buffer_length = f.size();
2104 if (QFile::exists(_filename)) { 2110 save_buffer_length = ((save_buffer_length / 1024)+1) * 1024;
2105 val = checkFile(_filename);
2106 if (val != PWERR_GOOD)
2107 return val;
2108 } else
2109 {
2110 val = creat (_filename, (S_IRUSR | S_IWUSR));
2111 if (val == -1)
2112 return PWERR_OPEN;
2113 else
2114 close(val);
2115 }
2116*/
2117 QFileInfo f (_filename);
2118 save_buffer_length = f.size();
2119 save_buffer_length = ((save_buffer_length / 1024)+1) * 1024;
2120 2111
2121 fd = fopen (_filename, "wb"); 2112 fd = fopen (_filename, "wb");
2122 if (fd == NULL) 2113 if (fd == NULL) {
2114 delete krc2;
2123 return PWERR_OPEN; 2115 return PWERR_OPEN;
2116 }
2124 2117
2125 buffer = (char*)malloc(save_buffer_length); 2118 buffer = (char*)malloc(save_buffer_length);
2126 2119
2127 /* make the key ready */ 2120 /* make the key ready */
2128 for (j = 0; password[j] != '\0'; j++) { 2121 for (j = 0; password[j] != '\0'; j++) {
2129 key[j] = password[j]; 2122 key[j] = password[j];
2130 } 2123 }
2131 keylength = j; 2124 keylength = j;
2132 krc2->rc2_expandkey (key, keylength, 128); 2125 krc2->rc2_expandkey (key, keylength, 128);
2126 delete krc2;
2133 2127
2134 /* First, we make the IV */ 2128 /* First, we make the IV */
2135 for (count2 = 0; count2 < 4; count2++) { 2129 for (count2 = 0; count2 < 4; count2++) {
2136 iv[count2] = rand (); 2130 iv[count2] = rand ();
2137 putc ((unsigned char) (iv[count2] >> 8), fd); 2131 putc ((unsigned char) (iv[count2] >> 8), fd);
2138 putc ((unsigned char) (iv[count2] & 0xff), fd); 2132 putc ((unsigned char) (iv[count2] & 0xff), fd);
2139 } 2133 }
2140 2134
2141 bufferIndex = 0; 2135 bufferIndex = 0;
2142 return PWERR_GOOD; 2136 return PWERR_GOOD;
2143} 2137}
2144 2138
2145 2139
2146int ZSafe::saveEntry(char *entry[FIELD_SIZE]) 2140int ZSafe::saveEntry(char *entry[FIELD_SIZE])
2147{ 2141{
2148 char *text1; 2142 char *text1;
2149 int count2, count3; 2143 int count2, count3;
2150 unsigned short ciphertext[4]; 2144 unsigned short ciphertext[4];
2151 Krc2* krc2 = new Krc2(); 2145 Krc2* krc2 = new Krc2();
2152 2146
2153 buffer = (char*)memset(buffer, '\0', save_buffer_length); 2147 buffer = (char*)memset(buffer, '\0', save_buffer_length);
2154 2148
2155 for (count2 = 0; count2 < FIELD_SIZE; count2++) { 2149 for (count2 = 0; count2 < FIELD_SIZE; count2++) {
2156 text1 = entry[count2]; 2150 text1 = entry[count2];
2157 if (strlen (text1) == 0) { 2151 if (strlen (text1) == 0) {
2158 strncat(buffer, " ", strlen(" ")); 2152 strncat(buffer, " ", strlen(" "));
2159 } else { 2153 } else {
2160 strncat(buffer, text1, strlen(text1)); 2154 strncat(buffer, text1, strlen(text1));
2161 } 2155 }
2162 /* Use 255 as the marker. \n is too tough to test for */ 2156 /* Use 255 as the marker. \n is too tough to test for */
2163 buffer[strlen (buffer)] = 255; 2157 buffer[strlen (buffer)] = 255;
2164 } /*for (count2 = 0; count2 < 5; count2++)*/ 2158 } /*for (count2 = 0; count2 < 5; count2++)*/
2165 count2 = 0; 2159 count2 = 0;
2166 /* I'm using CBC mode and encrypting the data straight from top down. 2160 /* I'm using CBC mode and encrypting the data straight from top down.
2167 * At the bottom, encrypted, I will append an MD5 hash of the file, eventually. 2161 * At the bottom, encrypted, I will append an MD5 hash of the file, eventually.
2168 * PKCS 5 padding (explained at the code section 2162 * PKCS 5 padding (explained at the code section
2169 */ 2163 */
2170 while (count2 < (int)strlen (buffer)) { 2164 while (count2 < (int)strlen (buffer)) {
2171#ifndef WORDS_BIGENDIAN 2165#ifndef WORDS_BIGENDIAN
2172 plaintext[bufferIndex] = buffer[count2 + 1] << 8; 2166 plaintext[bufferIndex] = buffer[count2 + 1] << 8;
2173 plaintext[bufferIndex] += buffer[count2] & 0xff; 2167 plaintext[bufferIndex] += buffer[count2] & 0xff;
2174#endif 2168#endif
2175#ifdef WORDS_BIGENDIAN 2169#ifdef WORDS_BIGENDIAN
2176 plaintext[bufferIndex] = buffer[count2] << 8; 2170 plaintext[bufferIndex] = buffer[count2] << 8;
2177 plaintext[bufferIndex] += buffer[count2 + 1] & 0xff; 2171 plaintext[bufferIndex] += buffer[count2 + 1] & 0xff;
2178#endif 2172#endif
2179 bufferIndex++; 2173 bufferIndex++;
2180 if (bufferIndex == 4) { 2174 if (bufferIndex == 4) {
2181 krc2->rc2_encrypt (plaintext); 2175 krc2->rc2_encrypt (plaintext);
2182 2176
2183 for (count3 = 0; count3 < 4; count3++) { 2177 for (count3 = 0; count3 < 4; count3++) {
2184 ciphertext[count3] = iv[count3] ^ plaintext[count3]; 2178 ciphertext[count3] = iv[count3] ^ plaintext[count3];
2185 2179
2186 /* Now store the ciphertext as the iv */ 2180 /* Now store the ciphertext as the iv */
2187 iv[count3] = plaintext[count3]; 2181 iv[count3] = plaintext[count3];
2188 2182
2189 /* reset the buffer index */ 2183 /* reset the buffer index */
2190 bufferIndex = 0; 2184 bufferIndex = 0;
2191 if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) return PWERR_DATA; 2185 if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) {
2192 if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) return PWERR_DATA; 2186 delete krc2;
2187 return PWERR_DATA;
2188 }
2189 if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) {
2190 delete krc2;
2191 return PWERR_DATA;
2192 }
2193 } /*for (count3 = 0; count3 < 5; count3++)*/ 2193 } /*for (count3 = 0; count3 < 5; count3++)*/
2194 } /*if (bufferIndex == 5)*/ 2194 } /*if (bufferIndex == 5)*/
2195 /* increment a short, not a byte */ 2195 /* increment a short, not a byte */
2196 count2 += 2; 2196 count2 += 2;
2197 } /*while (count2 < strlen (buffer))*/ 2197 } /*while (count2 < strlen (buffer))*/
2198 int ret = PWERR_GOOD; 2198 delete krc2;
2199 return ret; 2199 return PWERR_GOOD;
2200} 2200}
2201 2201
2202int ZSafe::saveFinalize(void) 2202int ZSafe::saveFinalize(void)
2203{ 2203{
2204 int count1, retval = PWERR_GOOD; 2204 int count1, retval = PWERR_GOOD;
2205 unsigned short ciphertext[4]; 2205 unsigned short ciphertext[4];
2206 Krc2* krc2 = new Krc2(); 2206 Krc2* krc2 = new Krc2();
2207 2207
2208 /* Tack on the PKCS 5 padding 2208 /* Tack on the PKCS 5 padding
2209 * How it works is we fill up the last n bytes with the value n 2209 * How it works is we fill up the last n bytes with the value n
2210 * 2210 *
2211 * So, if we have, say, 13 bytes, 8 of which are used, we have 5 left 2211 * So, if we have, say, 13 bytes, 8 of which are used, we have 5 left
2212 * over, leaving us 3 short, so we fill it in with 3's. 2212 * over, leaving us 3 short, so we fill it in with 3's.
2213 * 2213 *
2214 * If we come out even, we fill it with 8 8s 2214 * If we come out even, we fill it with 8 8s
2215 * 2215 *
2216 * um, except that in this instance we are using 4 shorts instead of 8 bytes. 2216 * um, except that in this instance we are using 4 shorts instead of 8 bytes.
2217 * so, half everything 2217 * so, half everything
2218 */ 2218 */
2219 for (count1 = bufferIndex; count1 < 4; count1++) { 2219 for (count1 = bufferIndex; count1 < 4; count1++) {
2220 plaintext[count1] = (4 - bufferIndex); 2220 plaintext[count1] = (4 - bufferIndex);
2221 } 2221 }
2222 krc2->rc2_encrypt (plaintext); 2222 krc2->rc2_encrypt (plaintext);
2223 for (count1 = 0; count1 < 4; count1++) { 2223 for (count1 = 0; count1 < 4; count1++) {
2224 ciphertext[count1] = iv[count1] ^ plaintext[count1]; 2224 ciphertext[count1] = iv[count1] ^ plaintext[count1];
2225 if (putc ((unsigned char) (ciphertext[count1] >> 8), fd) == EOF) retval = PWERR_DATA; 2225 if (putc ((unsigned char) (ciphertext[count1] >> 8), fd) == EOF) retval = PWERR_DATA;
2226 if (putc ((unsigned char) (ciphertext[count1] & 0xff), fd) == EOF) retval = PWERR_DATA; 2226 if (putc ((unsigned char) (ciphertext[count1] & 0xff), fd) == EOF) retval = PWERR_DATA;
2227 } 2227 }
2228 2228
2229 fclose (fd); 2229 fclose (fd);
2230 free(buffer); 2230 free(buffer);
2231 delete krc2;
2231 return retval; 2232 return retval;
2232} 2233}
2233 2234
2234void ZSafe::quitMe () 2235void ZSafe::quitMe ()
2235{ 2236{
2236 if (modified) 2237 if (modified)
2237 { 2238 {
2238 switch( QMessageBox::information( this, tr("ZSafe"), 2239 switch( QMessageBox::information( this, tr("ZSafe"),
2239 tr("Do you want to save\nbefore exiting?"), 2240 tr("Do you want to save\nbefore exiting?"),
2240 tr("&Save"), 2241 tr("&Save"),
2241 tr("S&ave with\nnew\npassword"), 2242 tr("S&ave with\nnew\npassword"),
2242 tr("&Don't Save"), 2243 tr("&Don't Save"),
2243 0 // Enter == button 0 2244 0 // Enter == button 0
2244 ) ) 2245 ) )
2245 { // Escape == button 2 2246 { // Escape == button 2
2246 case 0: // Save clicked, Alt-S or Enter pressed. 2247 case 0: // Save clicked, Alt-S or Enter pressed.
2247 // save 2248 // save
2248 modified = false; 2249 modified = false;
2249 saveDocument(filename, FALSE); 2250 saveDocument(filename, FALSE);
2250 exitZs (1); 2251 exitZs (1);
2251 break; 2252 break;
2252 case 1: // 2253 case 1: //
2253 // Save with new password 2254 // Save with new password
2254 modified = false; 2255 modified = false;
2255 saveDocument(filename, TRUE); 2256 saveDocument(filename, TRUE);
2256 exitZs (1); 2257 exitZs (1);
2257 break; 2258 break;
2258 case 2: // Don't Save clicked or Alt-D pressed 2259 case 2: // Don't Save clicked or Alt-D pressed
2259 // don't save but exitZs 2260 // don't save but exitZs
2260 exitZs (1); 2261 exitZs (1);
2261 break; 2262 break;
2262 } 2263 }
2263 } 2264 }
2264 exitZs (1); 2265 exitZs (1);
2265 2266
2266} 2267}
2267 2268
2268void ZSafe::categoryFieldActivated( const QString& category) 2269void ZSafe::categoryFieldActivated( const QString& category)
2269{ 2270{
2270 if (categoryDialog) 2271 if (categoryDialog)
2271 setCategoryDialogFields(categoryDialog, category); 2272 setCategoryDialogFields(categoryDialog, category);
2272} 2273}
2273 2274
2274void ZSafe::addCategory() 2275void ZSafe::addCategory()
2275{ 2276{
2276 if (filename.isEmpty()) 2277 if (filename.isEmpty())
2277 { 2278 {
2278 QMessageBox::critical( 0, tr("ZSafe"), 2279 QMessageBox::critical( 0, tr("ZSafe"),
2279 tr("No document defined.\nYou have to create a new document")); 2280 tr("No document defined.\nYou have to create a new document"));
2280 return; 2281 return;
2281 } 2282 }
2282 else 2283 else
2283 { 2284 {
2284 // open the 'Category' dialog 2285 // open the 'Category' dialog
2285 bool initIcons = false; 2286 bool initIcons = false;
2286 // open the 'Category' dialog 2287 // open the 'Category' dialog
2287 CategoryDialog *dialog; 2288 CategoryDialog *dialog;
2288 if (categoryDialog) 2289 if (categoryDialog)
2289 { 2290 {
2290 dialog = categoryDialog; 2291 dialog = categoryDialog;
2291 } 2292 }
2292 else 2293 else
2293 { 2294 {
2294 categoryDialog = new CategoryDialog(this, tr("Category"), TRUE); 2295 categoryDialog = new CategoryDialog(this, tr("Category"), TRUE);
2295 dialog = categoryDialog; 2296 dialog = categoryDialog;
2296 connect( dialog->CategoryField, 2297 connect( dialog->CategoryField,
2297 SIGNAL( activated(const QString&)), 2298 SIGNAL( activated(const QString&)),
2298 this, SLOT( categoryFieldActivated(const QString&) ) ); 2299 this, SLOT( categoryFieldActivated(const QString&) ) );
2299 initIcons = true; 2300 initIcons = true;
2300 } 2301 }
2301 2302
2302 // read all categories from the config file and store 2303 // read all categories from the config file and store
2303 // into a list 2304 // into a list
2304 QFile f (cfgFile); 2305 QFile f (cfgFile);
2305 QStringList list; 2306 QStringList list;
2306 if ( f.open(IO_ReadOnly) ) { // file opened successfully 2307 if ( f.open(IO_ReadOnly) ) { // file opened successfully
2307 QTextStream t( &f ); // use a text stream 2308 QTextStream t( &f ); // use a text stream
2308 QString s; 2309 QString s;
2309 while ( !t.eof() ) { // until end of file... 2310 while ( !t.eof() ) { // until end of file...
2310 s = t.readLine(); // line of text excluding '\n' 2311 s = t.readLine(); // line of text excluding '\n'
2311 list.append(s); 2312 list.append(s);
2312 } 2313 }
2313 f.close(); 2314 f.close();
2314 } 2315 }
2315 QStringList::Iterator it = list.begin(); 2316 QStringList::Iterator it = list.begin();
2316 QString categ; 2317 QString categ;
2317 QString firstCategory; 2318 QString firstCategory;
2318 dialog->CategoryField->clear(); // remove all items 2319 dialog->CategoryField->clear(); // remove all items
2319 while( it != list.end() ) 2320 while( it != list.end() )
2320 { 2321 {
2321 QString *cat = new QString (*it); 2322 QString *cat = new QString (*it);
2322 if (cat->contains("-field1", FALSE)) 2323 if (cat->contains("-field1", FALSE))
2323 { 2324 {
2324 int pos = cat->find ("-field1"); 2325 int pos = cat->find ("-field1");
2325 cat->truncate(pos); 2326 cat->truncate(pos);
2326 categ = *cat; 2327 categ = *cat;
2327 if (!categ.isEmpty()) 2328 if (!categ.isEmpty())
2328 { 2329 {
2329 dialog->CategoryField->insertItem (categ, -1); 2330 dialog->CategoryField->insertItem (categ, -1);
2330 if (firstCategory.isEmpty()) 2331 if (firstCategory.isEmpty())
2331 firstCategory = categ; 2332 firstCategory = categ;
2332 } 2333 }
2333 } 2334 }
2334 ++it; 2335 ++it;
2335 } 2336 }
2336 2337
2337 2338
2338 if (firstCategory.isEmpty()) 2339 if (firstCategory.isEmpty())
2339 setCategoryDialogFields(dialog); 2340 setCategoryDialogFields(dialog);
2340 else 2341 else
2341 setCategoryDialogFields(dialog, firstCategory); 2342 setCategoryDialogFields(dialog, firstCategory);
2342 2343
2343 // CategoryDialog *dialog = new CategoryDialog(this, "Category", TRUE); 2344 // CategoryDialog *dialog = new CategoryDialog(this, "Category", TRUE);
2344 2345
2345 if (initIcons) 2346 if (initIcons)
2346 { 2347 {
2347 Wait waitDialog(this, tr("Wait dialog")); 2348 Wait waitDialog(this, tr("Wait dialog"));
2348 waitDialog.waitLabel->setText(tr("Gathering icons...")); 2349 waitDialog.waitLabel->setText(tr("Gathering icons..."));
2349 waitDialog.show(); 2350 waitDialog.show();
2350 qApp->processEvents(); 2351 qApp->processEvents();
2351 2352
2352 QDir d(QPEApplication::qpeDir() + "pics/"); 2353 QDir d(QPEApplication::qpeDir() + "pics/");
2353 d.setFilter( QDir::Files); 2354 d.setFilter( QDir::Files);
2354 2355
2355 const QFileInfoList *list = d.entryInfoList(); 2356 const QFileInfoList *list = d.entryInfoList();
2356 QFileInfoListIterator it( *list ); // create list iterator 2357 QFileInfoListIterator it( *list ); // create list iterator
2357 QFileInfo *fi; // pointer for traversing 2358 QFileInfo *fi; // pointer for traversing
2358 2359
2359 dialog->IconField->insertItem("predefined"); 2360 dialog->IconField->insertItem("predefined");
2360 while ( (fi=it.current()) ) { // for each file... 2361 while ( (fi=it.current()) ) { // for each file...
2361 QString fileName = fi->fileName(); 2362 QString fileName = fi->fileName();
2362 if(fileName.right(4) == ".png"){ 2363 if(fileName.right(4) == ".png"){
2363 fileName = fileName.mid(0,fileName.length()-4); 2364 fileName = fileName.mid(0,fileName.length()-4);
2364 QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon)); 2365 QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon));
2365 dialog->IconField->insertItem(imageOfFile,fileName); 2366 dialog->IconField->insertItem(imageOfFile,fileName);
2366 } 2367 }
2367 ++it; 2368 ++it;
2368 } 2369 }
2369 waitDialog.hide(); 2370 waitDialog.hide();
2370 } 2371 }
2371 2372
2372 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); 2373 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec();
2373 QString category; 2374 QString category;
2374 QString icon; 2375 QString icon;
2375 QString fullIconPath; 2376 QString fullIconPath;
2376 QPixmap *pix; 2377 QPixmap *pix;
2377 if (result == QDialog::Accepted) 2378 if (result == QDialog::Accepted)
2378 { 2379 {
2379 modified = true; 2380 modified = true;
2380 category = dialog->CategoryField->currentText(); 2381 category = dialog->CategoryField->currentText();
2381 icon = dialog->IconField->currentText()+".png"; 2382 icon = dialog->IconField->currentText()+".png";
2382 2383
2383 QListViewItem *li = new ShadedListItem( 1, ListView ); 2384 QListViewItem *li = new ShadedListItem( 1, ListView );
2384 Category *c1 = new Category(); 2385 Category *c1 = new Category();
2385 c1->setCategoryName(category); 2386 c1->setCategoryName(category);
2386 2387
2387 // if (!icon.isEmpty() && !icon.isNull()) 2388 // if (!icon.isEmpty() && !icon.isNull())
2388 if (icon != "predefined.png") 2389 if (icon != "predefined.png")
2389 { 2390 {
2390 // build the full path 2391 // build the full path
2391 fullIconPath = iconPath + icon; 2392 fullIconPath = iconPath + icon;
2392 pix = new QPixmap (fullIconPath); 2393 pix = new QPixmap (fullIconPath);
2393 // pix->resize(14, 14); 2394 // pix->resize(14, 14);
2394 if (!pix->isNull()) 2395 if (!pix->isNull())
2395 { 2396 {
2396 // save the full pixmap name into the config file 2397 // save the full pixmap name into the config file
2397// #ifndef Q_WS_WIN 2398// #ifndef Q_WS_WIN
2398 conf->writeEntry(APP_KEY+category, icon); 2399 conf->writeEntry(APP_KEY+category, icon);
2399// #endif 2400// #endif
2400 saveConf(); 2401 saveConf();
2401 QImage img = pix->convertToImage(); 2402 QImage img = pix->convertToImage();
2402 pix->convertFromImage(img.smoothScale(14,14)); 2403 pix->convertFromImage(img.smoothScale(14,14));
2403 c1->setIcon (*pix); 2404 c1->setIcon (*pix);
2404 c1->setIconName(icon); 2405 c1->setIconName(icon);
2405 } 2406 }
2406 else 2407 else
2407 { 2408 {
2408 QPixmap folder( ( const char** ) general_data ); 2409 QPixmap folder( ( const char** ) general_data );
2409 c1->setIcon (folder); 2410 c1->setIcon (folder);
2410 } 2411 }
2411 } 2412 }
2412 else 2413 else
2413 { 2414 {
2414 c1->setIcon (*getPredefinedIcon(category)); 2415 c1->setIcon (*getPredefinedIcon(category));
2415 } 2416 }
2416 2417
2417 c1->setListItem (li); 2418 c1->setListItem (li);
2418 c1->initListItem(); 2419 c1->initListItem();
2419 categories.insert (c1->getCategoryName(), c1); 2420 categories.insert (c1->getCategoryName(), c1);
2420 2421
2421 saveCategoryDialogFields(dialog); 2422 saveCategoryDialogFields(dialog);
2422 } 2423 }
2423 else 2424 else
2424 { 2425 {
2425 // delete dialog; 2426 // delete dialog;
2426 dialog->hide(); 2427 dialog->hide();
2427 return; 2428 return;
2428 } 2429 }
2429 2430
2430 } 2431 }
2431 2432
2432} 2433}
2433 2434
2434void ZSafe::delCategory() 2435void ZSafe::delCategory()
2435{ 2436{
2436 if (!selectedItem) 2437 if (!selectedItem)
2437 return; 2438 return;
2438 if (isCategory(selectedItem)) 2439 if (isCategory(selectedItem))
2439 { 2440 {
2440 switch( QMessageBox::information( this, tr("ZSafe"), 2441 switch( QMessageBox::information( this, tr("ZSafe"),
2441 tr("Do you want to delete?"), 2442 tr("Do you want to delete?"),
2442 tr("&Delete"), tr("D&on't Delete"), 2443 tr("&Delete"), tr("D&on't Delete"),
2443 0 // Enter == button 0 2444 0 // Enter == button 0
2444 ) ) { // Escape == button 2 2445 ) ) { // Escape == button 2
2445 case 0: // Delete clicked, Alt-S or Enter pressed. 2446 case 0: // Delete clicked, Alt-S or Enter pressed.
2446 // Delete from the category list 2447 // Delete from the category list
2447 modified = true; 2448 modified = true;
2448 categories.remove (selectedItem->text(0)); 2449 categories.remove (selectedItem->text(0));
2449// #ifndef Q_WS_WIN 2450// #ifndef Q_WS_WIN
2450 conf->removeEntry (selectedItem->text(0)); 2451 conf->removeEntry (selectedItem->text(0));
2451// #endif 2452// #endif
2452 saveConf(); 2453 saveConf();
2453 2454
2454 // Delete the selected item and all subitems 2455 // Delete the selected item and all subitems
2455 // step through all subitems 2456 // step through all subitems
2456 QListViewItem *si; 2457 QListViewItem *si;
2457 for (si = selectedItem->firstChild(); 2458 for (si = selectedItem->firstChild();
2458 si != NULL; ) 2459 si != NULL; )
2459 { 2460 {
2460 QListViewItem *_si = si; 2461 QListViewItem *_si = si;
2461 si = si->nextSibling(); 2462 si = si->nextSibling();
2462 selectedItem->takeItem(_si); // remove from view list 2463 selectedItem->takeItem(_si); // remove from view list
2463 if (_si) delete _si; 2464 if (_si) delete _si;
2464 } 2465 }
2465 ListView->takeItem(selectedItem); 2466 ListView->takeItem(selectedItem);
2466 delete selectedItem; 2467 delete selectedItem;
2467 2468
2468 selectedItem = NULL; 2469 selectedItem = NULL;
2469 break; 2470 break;
2470 case 1: // Don't delete 2471 case 1: // Don't delete
2471 break; 2472 break;
2472 } 2473 }
2473 2474
2474 } 2475 }
2475} 2476}
2476 2477
2477void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) 2478void ZSafe::setCategoryDialogFields(CategoryDialog *dialog)
2478{ 2479{
2479 if (!dialog) 2480 if (!dialog)
2480 return; 2481 return;
2481 2482
2482 QString icon; 2483 QString icon;
2483 if (selectedItem) 2484 if (selectedItem)
2484 { 2485 {
2485 dialog->Field1->setText(getFieldLabel (selectedItem, "1", tr("Name"))); 2486 dialog->Field1->setText(getFieldLabel (selectedItem, "1", tr("Name")));
2486 dialog->Field2->setText(getFieldLabel (selectedItem, "2", tr("Username"))); 2487 dialog->Field2->setText(getFieldLabel (selectedItem, "2", tr("Username")));
2487 dialog->Field3->setText(getFieldLabel (selectedItem, "3", tr("Password"))); 2488 dialog->Field3->setText(getFieldLabel (selectedItem, "3", tr("Password")));
2488 dialog->Field4->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); 2489 dialog->Field4->setText(getFieldLabel (selectedItem, "4", tr("Comment")));
2489 dialog->Field5->setText(getFieldLabel (selectedItem, "5", tr("Field 4"))); 2490 dialog->Field5->setText(getFieldLabel (selectedItem, "5", tr("Field 4")));
2490 dialog->Field6->setText(getFieldLabel (selectedItem, "6", tr("Field 5"))); 2491 dialog->Field6->setText(getFieldLabel (selectedItem, "6", tr("Field 5")));
2491 2492
2492 Category *cat= categories.find (selectedItem->text(0)); 2493 Category *cat= categories.find (selectedItem->text(0));
2493 if (cat) 2494 if (cat)
2494 { 2495 {
2495 icon = cat->getIconName(); 2496 icon = cat->getIconName();
2496 } 2497 }
2497 else 2498 else
2498 icon = conf->readEntry(APP_KEY+selectedItem->text(0)); 2499 icon = conf->readEntry(APP_KEY+selectedItem->text(0));
2499 } 2500 }
2500 else 2501 else
2501 { 2502 {
2502 dialog->Field1->setText(tr("Name")); 2503 dialog->Field1->setText(tr("Name"));
2503 dialog->Field2->setText(tr("Username")); 2504 dialog->Field2->setText(tr("Username"));
2504 dialog->Field3->setText(tr("Password")); 2505 dialog->Field3->setText(tr("Password"));
2505 dialog->Field4->setText(tr("Comment")); 2506 dialog->Field4->setText(tr("Comment"));
2506 dialog->Field5->setText(tr("Field 4")); 2507 dialog->Field5->setText(tr("Field 4"));
2507 dialog->Field6->setText(tr("Field 5")); 2508 dialog->Field6->setText(tr("Field 5"));
2508 } 2509 }
2509 2510
2510 QDir d(QPEApplication::qpeDir() + "pics/"); 2511 QDir d(QPEApplication::qpeDir() + "pics/");
2511 d.setFilter( QDir::Files); 2512 d.setFilter( QDir::Files);
2512 2513
2513 const QFileInfoList *list = d.entryInfoList(); 2514 const QFileInfoList *list = d.entryInfoList();
2514 int i=0; 2515 int i=0;
2515 QFileInfoListIterator it( *list ); // create list iterator 2516 QFileInfoListIterator it( *list ); // create list iterator
2516 QFileInfo *fi; // pointer for traversing 2517 QFileInfo *fi; // pointer for traversing
2517 if (icon.isEmpty() || icon.isNull()) 2518 if (icon.isEmpty() || icon.isNull())
2518 { 2519 {
2519 dialog->IconField->setCurrentItem(0); 2520 dialog->IconField->setCurrentItem(0);
2520 } 2521 }
2521 else 2522 else
2522 { 2523 {
2523 while ( (fi=it.current()) ) 2524 while ( (fi=it.current()) )
2524 { // for each file... 2525 { // for each file...
2525 QString fileName = fi->fileName(); 2526 QString fileName = fi->fileName();
2526 if(fileName.right(4) == ".png") 2527 if(fileName.right(4) == ".png")
2527 { 2528 {
2528 fileName = fileName.mid(0,fileName.length()-4); 2529 fileName = fileName.mid(0,fileName.length()-4);
2529 2530
2530 if(fileName+".png"==icon) 2531 if(fileName+".png"==icon)
2531 { 2532 {
2532 dialog->IconField->setCurrentItem(i+1); 2533 dialog->IconField->setCurrentItem(i+1);
2533 break; 2534 break;
2534 } 2535 }
2535 ++i; 2536 ++i;
2536 } 2537 }
2537 ++it; 2538 ++it;
2538 } 2539 }
2539 } 2540 }
2540} 2541}
2541 2542
2542void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) 2543void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category)
2543{ 2544{
2544 if (!dialog) 2545 if (!dialog)
2545 return; 2546 return;
2546 2547
2547 dialog->Field1->setText(getFieldLabel (category, "1", tr("Name"))); 2548 dialog->Field1->setText(getFieldLabel (category, "1", tr("Name")));
2548 dialog->Field2->setText(getFieldLabel (category, "2", tr("Username"))); 2549 dialog->Field2->setText(getFieldLabel (category, "2", tr("Username")));
2549 dialog->Field3->setText(getFieldLabel (category, "3", tr("Password"))); 2550 dialog->Field3->setText(getFieldLabel (category, "3", tr("Password")));
2550 dialog->Field4->setText(getFieldLabel (category, "4", tr("Comment"))); 2551 dialog->Field4->setText(getFieldLabel (category, "4", tr("Comment")));
2551 dialog->Field5->setText(getFieldLabel (category, "5", tr("Field 4"))); 2552 dialog->Field5->setText(getFieldLabel (category, "5", tr("Field 4")));
2552 dialog->Field6->setText(getFieldLabel (category, "6", tr("Field 5"))); 2553 dialog->Field6->setText(getFieldLabel (category, "6", tr("Field 5")));
2553 2554
2554 QString icon; 2555 QString icon;
2555 Category *cat= categories.find (category); 2556 Category *cat= categories.find (category);
2556 if (cat) 2557 if (cat)
2557 { 2558 {
2558 icon = cat->getIconName(); 2559 icon = cat->getIconName();
2559 } 2560 }
2560 else 2561 else
2561 icon = conf->readEntry(APP_KEY+category); 2562 icon = conf->readEntry(APP_KEY+category);
2562 2563
2563 QDir d(QPEApplication::qpeDir() + "pics/"); 2564 QDir d(QPEApplication::qpeDir() + "pics/");
2564 d.setFilter( QDir::Files); 2565 d.setFilter( QDir::Files);
2565 2566
2566 const QFileInfoList *list = d.entryInfoList(); 2567 const QFileInfoList *list = d.entryInfoList();
2567 int i=0; 2568 int i=0;
2568 QFileInfoListIterator it( *list ); // create list iterator 2569 QFileInfoListIterator it( *list ); // create list iterator
2569 QFileInfo *fi; // pointer for traversing 2570 QFileInfo *fi; // pointer for traversing
2570 if (icon.isEmpty() || icon.isNull()) 2571 if (icon.isEmpty() || icon.isNull())
2571 { 2572 {
2572 dialog->IconField->setCurrentItem(0); 2573 dialog->IconField->setCurrentItem(0);
2573 } 2574 }
2574 else 2575 else
2575 { 2576 {
2576 while ( (fi=it.current()) ) 2577 while ( (fi=it.current()) )
2577 { // for each file... 2578 { // for each file...
2578 QString fileName = fi->fileName(); 2579 QString fileName = fi->fileName();
2579 if(fileName.right(4) == ".png") 2580 if(fileName.right(4) == ".png")
2580 { 2581 {
2581 fileName = fileName.mid(0,fileName.length()-4); 2582 fileName = fileName.mid(0,fileName.length()-4);
2582 2583
2583 if(fileName+".png"==icon) 2584 if(fileName+".png"==icon)
2584 { 2585 {
2585 dialog->IconField->setCurrentItem(i+1); 2586 dialog->IconField->setCurrentItem(i+1);
2586 break; 2587 break;
2587 } 2588 }
2588 ++i; 2589 ++i;
2589 } 2590 }
2590 ++it; 2591 ++it;
2591 } 2592 }
2592 } 2593 }
2593} 2594}
2594 2595
2595void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) 2596void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog)
2596{ 2597{
2597 QString app_key = APP_KEY; 2598 QString app_key = APP_KEY;
2598 conf->setGroup( "fieldDefs" ); 2599 conf->setGroup( "fieldDefs" );
2599 QString category = dialog->CategoryField->currentText(); 2600 QString category = dialog->CategoryField->currentText();
2600// #ifndef Q_WS_WIN 2601// #ifndef Q_WS_WIN
2601 conf->writeEntry(app_key+category+"-field1", dialog->Field1->text()); 2602 conf->writeEntry(app_key+category+"-field1", dialog->Field1->text());
2602 conf->writeEntry(app_key+category+"-field2", dialog->Field2->text()); 2603 conf->writeEntry(app_key+category+"-field2", dialog->Field2->text());
2603 conf->writeEntry(app_key+category+"-field3", dialog->Field3->text()); 2604 conf->writeEntry(app_key+category+"-field3", dialog->Field3->text());
2604 conf->writeEntry(app_key+category+"-field4", dialog->Field4->text()); 2605 conf->writeEntry(app_key+category+"-field4", dialog->Field4->text());
2605 conf->writeEntry(app_key+category+"-field5", dialog->Field5->text()); 2606 conf->writeEntry(app_key+category+"-field5", dialog->Field5->text());
2606 conf->writeEntry(app_key+category+"-field6", dialog->Field6->text()); 2607 conf->writeEntry(app_key+category+"-field6", dialog->Field6->text());
2607// #endif 2608// #endif
2608 saveConf(); 2609 saveConf();
2609 conf->setGroup ("zsafe"); 2610 conf->setGroup ("zsafe");
2610} 2611}
2611 2612
2612void ZSafe::editCategory() 2613void ZSafe::editCategory()
2613{ 2614{
2614 if (!selectedItem) 2615 if (!selectedItem)
2615 return; 2616 return;
2616 if (isCategory(selectedItem)) 2617 if (isCategory(selectedItem))
2617 { 2618 {
2618 QString category = selectedItem->text(0); 2619 QString category = selectedItem->text(0);
2619 bool initIcons = false; 2620 bool initIcons = false;
2620 // open the 'Category' dialog 2621 // open the 'Category' dialog
2621 CategoryDialog *dialog; 2622 CategoryDialog *dialog;
2622 if (categoryDialog) 2623 if (categoryDialog)
2623 { 2624 {
2624 dialog = categoryDialog; 2625 dialog = categoryDialog;
2625 } 2626 }
2626 else 2627 else
2627 { 2628 {
2628 categoryDialog = new CategoryDialog(this, tr("Category"), TRUE); 2629 categoryDialog = new CategoryDialog(this, tr("Category"), TRUE);
2629 dialog = categoryDialog; 2630 dialog = categoryDialog;
2630 connect( dialog->CategoryField, 2631 connect( dialog->CategoryField,
2631 SIGNAL( activated(const QString&)), 2632 SIGNAL( activated(const QString&)),
2632 this, SLOT( categoryFieldActivated(const QString&) ) ); 2633 this, SLOT( categoryFieldActivated(const QString&) ) );
2633 initIcons = true; 2634 initIcons = true;
2634 } 2635 }
2635 setCategoryDialogFields(dialog); 2636 setCategoryDialogFields(dialog);
2636 2637
2637 // read all categories from the config file and store 2638 // read all categories from the config file and store
2638 // into a list 2639 // into a list
2639 QFile f (cfgFile); 2640 QFile f (cfgFile);
2640 QStringList list; 2641 QStringList list;
2641 if ( f.open(IO_ReadOnly) ) { // file opened successfully 2642 if ( f.open(IO_ReadOnly) ) { // file opened successfully
2642 QTextStream t( &f ); // use a text stream 2643 QTextStream t( &f ); // use a text stream
2643 QString s; 2644 QString s;
2644 while ( !t.eof() ) { // until end of file... 2645 while ( !t.eof() ) { // until end of file...
2645 s = t.readLine(); // line of text excluding '\n' 2646 s = t.readLine(); // line of text excluding '\n'
2646 list.append(s); 2647 list.append(s);
2647 } 2648 }
2648 f.close(); 2649 f.close();
2649 } 2650 }
2650 QStringList::Iterator it = list.begin(); 2651 QStringList::Iterator it = list.begin();
2651 QString categ; 2652 QString categ;
2652 dialog->CategoryField->clear(); // remove all items 2653 dialog->CategoryField->clear(); // remove all items
2653 int i=0; 2654 int i=0;
2654 bool foundCategory = false; 2655 bool foundCategory = false;
2655 while( it != list.end() ) 2656 while( it != list.end() )
2656 { 2657 {
2657 QString *cat = new QString (*it); 2658 QString *cat = new QString (*it);
2658 if (cat->contains("-field1", FALSE)) 2659 if (cat->contains("-field1", FALSE))
2659 { 2660 {
2660 int pos = cat->find ("-field1"); 2661 int pos = cat->find ("-field1");
2661 cat->truncate(pos); 2662 cat->truncate(pos);
2662 categ = *cat; 2663 categ = *cat;
2663 if (!categ.isEmpty()) 2664 if (!categ.isEmpty())
2664 { 2665 {
2665 dialog->CategoryField->insertItem (categ, i); 2666 dialog->CategoryField->insertItem (categ, i);
2666 if (category.compare(categ) == 0) 2667 if (category.compare(categ) == 0)
2667 { 2668 {
2668 dialog->CategoryField->setCurrentItem(i); 2669 dialog->CategoryField->setCurrentItem(i);
2669 foundCategory = true; 2670 foundCategory = true;
2670 } 2671 }
2671 i++; 2672 i++;
2672 } 2673 }
2673 } 2674 }
2674 ++it; 2675 ++it;
2675 } 2676 }
2676 if (!foundCategory) 2677 if (!foundCategory)
2677 { 2678 {
2678 dialog->CategoryField->insertItem (category, i); 2679 dialog->CategoryField->insertItem (category, i);
2679 dialog->CategoryField->setCurrentItem(i); 2680 dialog->CategoryField->setCurrentItem(i);
2680 } 2681 }
2681 2682
2682 QString icon; 2683 QString icon;
2683 Category *cat= categories.find (selectedItem->text(0)); 2684 Category *cat= categories.find (selectedItem->text(0));
2684 if (cat) 2685 if (cat)
2685 { 2686 {
2686 icon = cat->getIconName(); 2687 icon = cat->getIconName();
2687 } 2688 }
2688 2689
2689 if (initIcons) 2690 if (initIcons)
2690 { 2691 {
2691 2692
2692 Wait waitDialog(this, tr("Wait dialog")); 2693 Wait waitDialog(this, tr("Wait dialog"));
2693 waitDialog.waitLabel->setText(tr("Gathering icons...")); 2694 waitDialog.waitLabel->setText(tr("Gathering icons..."));
2694 waitDialog.show(); 2695 waitDialog.show();
2695 qApp->processEvents(); 2696 qApp->processEvents();
2696 2697
2697 QDir d(QPEApplication::qpeDir() + "pics/"); 2698 QDir d(QPEApplication::qpeDir() + "pics/");
2698 d.setFilter( QDir::Files); 2699 d.setFilter( QDir::Files);
2699 2700
2700 const QFileInfoList *list = d.entryInfoList(); 2701 const QFileInfoList *list = d.entryInfoList();
2701 int i=0; 2702 int i=0;
2702 QFileInfoListIterator it( *list ); // create list iterator 2703 QFileInfoListIterator it( *list ); // create list iterator
2703 QFileInfo *fi; // pointer for traversing 2704 QFileInfo *fi; // pointer for traversing
2704 if (icon.isEmpty() || icon.isNull()) 2705 if (icon.isEmpty() || icon.isNull())
2705 { 2706 {
2706 dialog->IconField->setCurrentItem(0); 2707 dialog->IconField->setCurrentItem(0);
2707 } 2708 }
2708 2709
2709 dialog->IconField->insertItem("predefined"); 2710 dialog->IconField->insertItem("predefined");
2710 while ( (fi=it.current()) ) { // for each file... 2711 while ( (fi=it.current()) ) { // for each file...
2711 QString fileName = fi->fileName(); 2712 QString fileName = fi->fileName();
2712 if(fileName.right(4) == ".png") 2713 if(fileName.right(4) == ".png")
2713 { 2714 {
2714 fileName = fileName.mid(0,fileName.length()-4); 2715 fileName = fileName.mid(0,fileName.length()-4);
2715 QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon)); 2716 QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon));
2716 dialog->IconField->insertItem(imageOfFile,fileName); 2717 dialog->IconField->insertItem(imageOfFile,fileName);
2717 if(fileName+".png"==icon) 2718 if(fileName+".png"==icon)
2718 dialog->IconField->setCurrentItem(i+1); 2719 dialog->IconField->setCurrentItem(i+1);
2719 ++i; 2720 ++i;
2720 } 2721 }
2721 ++it; 2722 ++it;
2722 } 2723 }
2723 waitDialog.hide(); 2724 waitDialog.hide();
2724 } 2725 }
2725 else 2726 else
2726 { 2727 {
2727 QDir d(QPEApplication::qpeDir() + "pics/"); 2728 QDir d(QPEApplication::qpeDir() + "pics/");
2728 d.setFilter( QDir::Files); 2729 d.setFilter( QDir::Files);
2729 2730
2730 const QFileInfoList *list = d.entryInfoList(); 2731 const QFileInfoList *list = d.entryInfoList();
2731 int i=0; 2732 int i=0;
2732 QFileInfoListIterator it( *list ); // create list iterator 2733 QFileInfoListIterator it( *list ); // create list iterator
2733 QFileInfo *fi; // pointer for traversing 2734 QFileInfo *fi; // pointer for traversing
2734 if (icon.isEmpty() || icon.isNull()) 2735 if (icon.isEmpty() || icon.isNull())
2735 { 2736 {
2736 dialog->IconField->setCurrentItem(0); 2737 dialog->IconField->setCurrentItem(0);
2737 } 2738 }
2738 else 2739 else
2739 { 2740 {
2740 2741
2741 while ( (fi=it.current()) ) 2742 while ( (fi=it.current()) )
2742 { // for each file... 2743 { // for each file...
2743 QString fileName = fi->fileName(); 2744 QString fileName = fi->fileName();
2744 if(fileName.right(4) == ".png") 2745 if(fileName.right(4) == ".png")
2745 { 2746 {
2746 fileName = fileName.mid(0,fileName.length()-4); 2747 fileName = fileName.mid(0,fileName.length()-4);
2747 2748
2748 2749
2749 if(fileName+".png"==icon) 2750 if(fileName+".png"==icon)
2750 { 2751 {
2751 dialog->IconField->setCurrentItem(i+1); 2752 dialog->IconField->setCurrentItem(i+1);
2752 break; 2753 break;
2753 } 2754 }
2754 ++i; 2755 ++i;
2755 } 2756 }
2756 ++it; 2757 ++it;
2757 } 2758 }
2758 } 2759 }
2759 } 2760 }
2760 2761
2761 // dialog->show(); 2762 // dialog->show();
2762 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); 2763 QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec();
2763 2764
2764 QString fullIconPath; 2765 QString fullIconPath;
2765 QPixmap *pix; 2766 QPixmap *pix;
2766 if (result == QDialog::Accepted) 2767 if (result == QDialog::Accepted)
2767 { 2768 {
2768 modified = true; 2769 modified = true;
2769 if (category != dialog->CategoryField->currentText()) 2770 if (category != dialog->CategoryField->currentText())
2770 { 2771 {
2771 categories.remove (category); 2772 categories.remove (category);
2772// #ifndef Q_WS_WIN 2773// #ifndef Q_WS_WIN
2773 conf->removeEntry(category); 2774 conf->removeEntry(category);
2774// #endif 2775// #endif
2775 saveConf(); 2776 saveConf();
2776 } 2777 }
2777 2778
2778 category = dialog->CategoryField->currentText(); 2779 category = dialog->CategoryField->currentText();
2779 icon = dialog->IconField->currentText()+".png"; 2780 icon = dialog->IconField->currentText()+".png";
2780 2781
2781 if (cat) 2782 if (cat)
2782 { 2783 {
2783 // if (!icon.isEmpty() && !icon.isNull()) 2784 // if (!icon.isEmpty() && !icon.isNull())
2784 if (icon != "predefined.png") 2785 if (icon != "predefined.png")
2785 { 2786 {
2786 // build the full path 2787 // build the full path
2787 fullIconPath = iconPath + icon; 2788 fullIconPath = iconPath + icon;
2788 pix = new QPixmap (fullIconPath); 2789 pix = new QPixmap (fullIconPath);
2789 if (!pix->isNull()) 2790 if (!pix->isNull())
2790 { 2791 {
2791 // save the full pixmap name into the config file 2792 // save the full pixmap name into the config file
2792// #ifndef Q_WS_WIN 2793// #ifndef Q_WS_WIN
2793 conf->writeEntry(APP_KEY+category, icon); 2794 conf->writeEntry(APP_KEY+category, icon);
2794// #endif 2795// #endif
2795 saveConf(); 2796 saveConf();
2796 QImage img = pix->convertToImage(); 2797 QImage img = pix->convertToImage();
2797 pix->convertFromImage(img.smoothScale(14,14)); 2798 pix->convertFromImage(img.smoothScale(14,14));
2798 cat->setIconName (icon); 2799 cat->setIconName (icon);
2799 cat->setIcon (*pix); 2800 cat->setIcon (*pix);
2800 } 2801 }
2801 } 2802 }
2802 else 2803 else
2803 { 2804 {
2804// #ifndef Q_WS_WIN 2805// #ifndef Q_WS_WIN
2805 conf->removeEntry (category); 2806 conf->removeEntry (category);
2806// #endif 2807// #endif
2807 saveConf(); 2808 saveConf();
2808 cat->setIcon (*getPredefinedIcon(category)); 2809 cat->setIcon (*getPredefinedIcon(category));
2809 } 2810 }
2810 2811
2811 // change the category name of the selected category 2812 // change the category name of the selected category
2812 QListViewItem *catItem = cat->getListItem(); 2813 QListViewItem *catItem = cat->getListItem();
2813 if (catItem) 2814 if (catItem)
2814 { 2815 {
2815 catItem->setText( 0, tr( category ) ); 2816 catItem->setText( 0, tr( category ) );
2816 cat->setCategoryName (tr(category)); 2817 cat->setCategoryName (tr(category));
2817 2818
2818 cat->initListItem(); 2819 cat->initListItem();
2819 categories.insert (category, cat); 2820 categories.insert (category, cat);
2820 } 2821 }
2821 } 2822 }
2822 saveCategoryDialogFields(dialog); 2823 saveCategoryDialogFields(dialog);
2823 } 2824 }
2824 else 2825 else
2825 { 2826 {
2826 // delete dialog; 2827 // delete dialog;
2827 dialog->hide(); 2828 dialog->hide();
2828 return; 2829 return;
2829 } 2830 }
2830 2831
2831 } 2832 }
2832} 2833}
2833 2834
2834void ZSafe::cutItem() 2835void ZSafe::cutItem()
2835{ 2836{
2836 if (!selectedItem) 2837 if (!selectedItem)
2837 return; 2838 return;
2838 if (!isCategory(selectedItem)) 2839 if (!isCategory(selectedItem))
2839 { 2840 {
2840 IsCut = true; 2841 IsCut = true;
2841 copiedItem = selectedItem; 2842 copiedItem = selectedItem;
2842 } 2843 }
2843} 2844}
2844 2845
2845void ZSafe::copyItem() 2846void ZSafe::copyItem()
2846{ 2847{
2847 if (!selectedItem) 2848 if (!selectedItem)
2848 return; 2849 return;
2849 if (!isCategory(selectedItem)) 2850 if (!isCategory(selectedItem))
2850 { 2851 {
2851 IsCopy = true; 2852 IsCopy = true;
2852 copiedItem = selectedItem; 2853 copiedItem = selectedItem;
2853 } 2854 }
2854} 2855}
2855 2856
2856// paste item into category 2857// paste item into category
2857void ZSafe::pasteItem() 2858void ZSafe::pasteItem()
2858{ 2859{
2859 if (!selectedItem) 2860 if (!selectedItem)
2860 return; 2861 return;
2861 if (isCategory(selectedItem)) 2862 if (isCategory(selectedItem))
2862 { 2863 {
2863 modified = true; 2864 modified = true;
2864 if (IsCut) 2865 if (IsCut)
2865 { 2866 {
2866 if (copiedItem) 2867 if (copiedItem)
2867 { 2868 {
2868 // add the new item 2869 // add the new item
2869 QListViewItem *i = new ShadedListItem (0, selectedItem); 2870 QListViewItem *i = new ShadedListItem (0, selectedItem);
2870 // i->setOpen (TRUE); 2871 // i->setOpen (TRUE);
2871 i->setText (0, copiedItem->text(0)); 2872 i->setText (0, copiedItem->text(0));
2872 i->setText (1, copiedItem->text(1)); 2873 i->setText (1, copiedItem->text(1));
2873 i->setText (2, copiedItem->text(2)); 2874 i->setText (2, copiedItem->text(2));
2874 i->setText (3, copiedItem->text(3)); 2875 i->setText (3, copiedItem->text(3));
2875 i->setText (4, copiedItem->text(4)); 2876 i->setText (4, copiedItem->text(4));
2876 i->setText (5, copiedItem->text(5)); 2877 i->setText (5, copiedItem->text(5));
2877 selectedItem->setOpen( TRUE ); 2878 selectedItem->setOpen( TRUE );
2878 2879
2879 // remove the cutted item 2880 // remove the cutted item
2880 copiedItem->parent()->takeItem(copiedItem); 2881 copiedItem->parent()->takeItem(copiedItem);
2881 selectedItem = NULL; 2882 selectedItem = NULL;
2882 } 2883 }
2883 } 2884 }
2884 else if (IsCopy) 2885 else if (IsCopy)
2885 { 2886 {
2886 if (copiedItem) 2887 if (copiedItem)
2887 { 2888 {
2888 // add the new item 2889 // add the new item
2889 QListViewItem *i = new ShadedListItem (0, selectedItem); 2890 QListViewItem *i = new ShadedListItem (0, selectedItem);
2890 // i->setOpen (TRUE); 2891 // i->setOpen (TRUE);
2891 i->setText (0, copiedItem->text(0)); 2892 i->setText (0, copiedItem->text(0));
2892 i->setText (1, copiedItem->text(1)); 2893 i->setText (1, copiedItem->text(1));
2893 i->setText (2, copiedItem->text(2)); 2894 i->setText (2, copiedItem->text(2));
2894 i->setText (3, copiedItem->text(3)); 2895 i->setText (3, copiedItem->text(3));
2895 i->setText (4, copiedItem->text(4)); 2896 i->setText (4, copiedItem->text(4));
2896 i->setText (5, copiedItem->text(5)); 2897 i->setText (5, copiedItem->text(5));
2897 selectedItem->setOpen( TRUE ); 2898 selectedItem->setOpen( TRUE );
2898 } 2899 }
2899 } 2900 }
2900 } 2901 }
2901 IsCut = false; 2902 IsCut = false;
2902 IsCopy = false; 2903 IsCopy = false;
2903} 2904}
2904 2905
2905void ZSafe::newDocument() 2906void ZSafe::newDocument()
2906{ 2907{
2907 2908
2908 // open the file dialog 2909 // open the file dialog
2909 QString newFile = zsaveDialog(); 2910 QString newFile = zsaveDialog();
2910 2911
2911 // open the new document 2912 // open the new document
2912 if (newFile && newFile.length() > 0 ) 2913 if (newFile && newFile.length() > 0 )
2913 { 2914 {
2914 // save the previous opened document 2915 // save the previous opened document
2915 if (!filename.isEmpty()) 2916 if (!filename.isEmpty())
2916 saveDocument(filename, FALSE); 2917 saveDocument(filename, FALSE);
2917 2918
2918 modified = true; 2919 modified = true;
2919 2920
2920 // clear the password list 2921 // clear the password list
2921 QListViewItem *i; 2922 QListViewItem *i;
2922 QListViewItem *c = NULL; 2923 QListViewItem *c = NULL;
2923 // step through all categories 2924 // step through all categories
2924 for (i = ListView->firstChild(); 2925 for (i = ListView->firstChild();
2925 i != NULL; 2926 i != NULL;
2926 i = i->nextSibling()) 2927 i = i->nextSibling())
2927 { 2928 {
2928 if (c) delete c; // delete the previous category 2929 if (c) delete c; // delete the previous category
2929 2930
2930 c = i; 2931 c = i;
2931 // step through all subitems 2932 // step through all subitems
2932 QListViewItem *si; 2933 QListViewItem *si;
2933 for (si = i->firstChild(); 2934 for (si = i->firstChild();
2934 si != NULL; ) 2935 si != NULL; )
2935 { 2936 {
2936 QListViewItem *_si = si; 2937 QListViewItem *_si = si;
2937 si = si->nextSibling(); 2938 si = si->nextSibling();
2938 i->takeItem(_si); // remove from view list 2939 i->takeItem(_si); // remove from view list
2939 if (_si) delete _si; 2940 if (_si) delete _si;
2940 } 2941 }
2941 } 2942 }
2942 if (c) delete c; // delete the previous category 2943 if (c) delete c; // delete the previous category
2943 categories.clear(); 2944 categories.clear();
2944 2945
2945 // m_password = ""; 2946 // m_password = "";
2946 selectedItem = NULL; 2947 selectedItem = NULL;
2947 2948
2948 filename = newFile; 2949 filename = newFile;
2949 2950
2950 // save the current filename to the config file 2951 // save the current filename to the config file
2951 conf->setGroup("zsafe"); 2952 conf->setGroup("zsafe");
2952 conf->writeEntry(APP_KEY+"document", filename); 2953 conf->writeEntry(APP_KEY+"document", filename);
2953 saveConf(); 2954 saveConf();
2954 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 2955 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
2955 this->setCaption(tr("ZSafe: ") + ti); 2956 this->setCaption(tr("ZSafe: ") + ti);
2956 2957
2957 // openDocument(filename); 2958 // openDocument(filename);
2958 2959
2959 QMessageBox::information( this, tr("ZSafe"), 2960 QMessageBox::information( this, tr("ZSafe"),
2960 tr("Now you have to enter\na password twice for your\nnewly created document."), tr("&OK"), 0); 2961 tr("Now you have to enter\na password twice for your\nnewly created document."), tr("&OK"), 0);
2961 2962
2962 saveDocumentWithPwd(); 2963 saveDocumentWithPwd();
2963 } 2964 }
2964} 2965}
2965 2966
2966void ZSafe::loadDocument() 2967void ZSafe::loadDocument()
2967{ 2968{
2968 2969
2969 // open the file dialog 2970 // open the file dialog
2970 QMap<QString, QStringList> mimeTypes; 2971 QMap<QString, QStringList> mimeTypes;
2971 mimeTypes.insert(tr("All"), QStringList() ); 2972 mimeTypes.insert(tr("All"), QStringList() );
2972 mimeTypes.insert(tr("ZSafe"), "zsafe/*" ); 2973 mimeTypes.insert(tr("ZSafe"), "zsafe/*" );
2973 QString newFile = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL, 2974 QString newFile = OFileDialog::getOpenFileName( OFileSelector::EXTENDED_ALL,
2974 QDir::homeDirPath() + "/Documents/application/zsafe", 2975 QDir::homeDirPath() + "/Documents/application/zsafe",
2975 QString::null, 2976 QString::null,
2976 mimeTypes, 2977 mimeTypes,
2977 this, 2978 this,
2978 tr ("Open ZSafe document")); 2979 tr ("Open ZSafe document"));
2979 2980
2980 // open the new document 2981 // open the new document
2981 if (newFile && newFile.length() > 0 ) 2982 if (newFile && newFile.length() > 0 )
2982 { 2983 {
2983 // save the previous opened document 2984 // save the previous opened document
2984 if (!filename.isEmpty()) 2985 if (!filename.isEmpty())
2985 saveDocument(filename, FALSE); 2986 saveDocument(filename, FALSE);
2986 2987
2987 // clear the password list 2988 // clear the password list
2988 QListViewItem *i; 2989 QListViewItem *i;
2989 QListViewItem *c = NULL; 2990 QListViewItem *c = NULL;
2990 // step through all categories 2991 // step through all categories
2991 for (i = ListView->firstChild(); 2992 for (i = ListView->firstChild();
2992 i != NULL; 2993 i != NULL;
2993 i = i->nextSibling()) 2994 i = i->nextSibling())
2994 { 2995 {
2995 if (c) delete c; // delete the previous category 2996 if (c) delete c; // delete the previous category
2996 2997
2997 c = i; 2998 c = i;
2998 // step through all subitems 2999 // step through all subitems
2999 QListViewItem *si; 3000 QListViewItem *si;
3000 for (si = i->firstChild(); 3001 for (si = i->firstChild();
3001 si != NULL; ) 3002 si != NULL; )
3002 { 3003 {
3003 QListViewItem *_si = si; 3004 QListViewItem *_si = si;
3004 si = si->nextSibling(); 3005 si = si->nextSibling();
3005 i->takeItem(_si); // remove from view list 3006 i->takeItem(_si); // remove from view list
3006 if (_si) delete _si; 3007 if (_si) delete _si;
3007 } 3008 }
3008 } 3009 }
3009 if (c) delete c; // delete the previous category 3010 if (c) delete c; // delete the previous category
3010 categories.clear(); 3011 categories.clear();
3011 m_password = ""; 3012 m_password = "";
3012 selectedItem = NULL; 3013 selectedItem = NULL;
3013 filename = newFile; 3014 filename = newFile;
3014 3015
3015 // save the current filename to the config file 3016 // save the current filename to the config file
3016 conf->setGroup("zsafe"); 3017 conf->setGroup("zsafe");
3017 conf->writeEntry(APP_KEY+"document", filename); 3018 conf->writeEntry(APP_KEY+"document", filename);
3018 saveConf(); 3019 saveConf();
3019 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 3020 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
3020 this->setCaption(tr("ZSafe: ") + ti); 3021 this->setCaption(tr("ZSafe: ") + ti);
3021 3022
3022 openDocument(filename); 3023 openDocument(filename);
3023 } 3024 }
3024} 3025}
3025 3026
3026void ZSafe::saveDocumentAs() 3027void ZSafe::saveDocumentAs()
3027{ 3028{
3028 3029
3029QString newFile = zsaveDialog(); 3030QString newFile = zsaveDialog();
3030 // open the new document 3031 // open the new document
3031 if (newFile && newFile.length() > 0 ) 3032 if (newFile && newFile.length() > 0 )
3032 { 3033 {
3033 // save the previous opened document 3034 // save the previous opened document
3034 if (!filename.isEmpty()) 3035 if (!filename.isEmpty())
3035 saveDocument(filename, FALSE); 3036 saveDocument(filename, FALSE);
3036 3037
3037 selectedItem = NULL; 3038 selectedItem = NULL;
3038 filename = newFile; 3039 filename = newFile;
3039 3040
3040 // save the current filename to the config file 3041 // save the current filename to the config file
3041 conf->setGroup("zsafe"); 3042 conf->setGroup("zsafe");
3042 conf->writeEntry(APP_KEY+"document", filename); 3043 conf->writeEntry(APP_KEY+"document", filename);
3043 saveConf(); 3044 saveConf();
3044 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 3045 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
3045 this->setCaption(tr("ZSafe: ") + ti); 3046 this->setCaption(tr("ZSafe: ") + ti);
3046 3047
3047 QMessageBox::information( this, tr("ZSafe"), 3048 QMessageBox::information( this, tr("ZSafe"),
3048 tr("Now you have to enter\na password twice for your\nnewly created document."), tr("&OK"), 0); 3049 tr("Now you have to enter\na password twice for your\nnewly created document."), tr("&OK"), 0);
3049 3050
3050 saveDocumentWithPwd(); 3051 saveDocumentWithPwd();
3051 } 3052 }
3052} 3053}
3053 3054
3054void ZSafe::saveDocumentWithoutPwd() 3055void ZSafe::saveDocumentWithoutPwd()
3055{ 3056{
3056 saveDocument(filename, FALSE); 3057 saveDocument(filename, FALSE);
3057} 3058}
3058 3059
3059void ZSafe::saveDocumentWithPwd() 3060void ZSafe::saveDocumentWithPwd()
3060{ 3061{
3061 saveDocument(filename, TRUE); 3062 saveDocument(filename, TRUE);
3062} 3063}
3063 3064
3064void ZSafe::setExpandFlag() 3065void ZSafe::setExpandFlag()
3065{ 3066{
3066 expandTree = !expandTree; 3067 expandTree = !expandTree;
3067 file->setItemChecked('o', expandTree); 3068 file->setItemChecked('o', expandTree);
3068 conf->setGroup ("zsafePrefs"); 3069 conf->setGroup ("zsafePrefs");
3069// #ifndef Q_WS_WIN 3070// #ifndef Q_WS_WIN
3070 conf->writeEntry (APP_KEY+"expandTree", expandTree); 3071 conf->writeEntry (APP_KEY+"expandTree", expandTree);
3071// #endif 3072// #endif
3072 saveConf(); 3073 saveConf();
3073 3074
3074} 3075}
3075 3076
3076void ZSafe::paintEvent( QPaintEvent * ) 3077void ZSafe::paintEvent( QPaintEvent * )
3077{ 3078{
3078 if (raiseFlag) 3079 if (raiseFlag)
3079 { 3080 {
3080 raiseFlag = false; 3081 raiseFlag = false;
3081 raiseTimer.start (1, true); 3082 raiseTimer.start (1, true);
3082 if (infoForm->isVisible()) 3083 if (infoForm->isVisible())
3083 infoForm->raise(); 3084 infoForm->raise();
3084 } 3085 }
3085} 3086}
3086 3087
3087void ZSafe::slotRaiseTimer() 3088void ZSafe::slotRaiseTimer()
3088{ 3089{
3089 if (infoForm->isVisible()) 3090 if (infoForm->isVisible())
3090 infoForm->raise(); 3091 infoForm->raise();
3091 raiseFlag = true; 3092 raiseFlag = true;
3092} 3093}
3093 3094
3094QPixmap * ZSafe::getPredefinedIcon(QString category) 3095QPixmap * ZSafe::getPredefinedIcon(QString category)
3095{ 3096{
3096 QPixmap *pm; 3097 QPixmap *pm;
3097 if (category == "Bank cards") 3098 if (category == "Bank cards")
3098 pm = new QPixmap((const char**)bank_cards_data); 3099 pm = new QPixmap((const char**)bank_cards_data);
3099 else if (category == "Passwords") 3100 else if (category == "Passwords")
3100 pm = new QPixmap((const char**)passwords_data); 3101 pm = new QPixmap((const char**)passwords_data);
3101 else if (category == "Software") 3102 else if (category == "Software")
3102 pm = new QPixmap((const char**)software_data); 3103 pm = new QPixmap((const char**)software_data);
3103 else if (category == "General") 3104 else if (category == "General")
3104 pm = new QPixmap((const char**)general_data); 3105 pm = new QPixmap((const char**)general_data);
3105 else 3106 else
3106 pm = new QPixmap((const char**)general_data); 3107 pm = new QPixmap((const char**)general_data);
3107 return pm; 3108 return pm;
3108} 3109}
3109 3110
3110void ZSafe::setDocument(const QString& fileref) 3111void ZSafe::setDocument(const QString& fileref)
3111{ 3112{
3112 // stop the timer to prevent loading of the default document 3113 // stop the timer to prevent loading of the default document
3113 docuTimer.stop(); 3114 docuTimer.stop();
3114 3115
3115 DocLnk link(fileref); 3116 DocLnk link(fileref);
3116 if ( link.isValid() ) 3117 if ( link.isValid() )
3117 { 3118 {
3118 // if (filename != link.file()) 3119 // if (filename != link.file())
3119 // saveDocument(filename, FALSE); 3120 // saveDocument(filename, FALSE);
3120 filename = link.file(); 3121 filename = link.file();
3121 } 3122 }
3122 else 3123 else
3123 { 3124 {
3124 // if (filename != fileref) 3125 // if (filename != fileref)
3125 // saveDocument(filename, FALSE); 3126 // saveDocument(filename, FALSE);
3126 filename = fileref; 3127 filename = fileref;
3127 } 3128 }
3128 // save the current filename to the config file 3129 // save the current filename to the config file
3129 conf->setGroup("zsafe"); 3130 conf->setGroup("zsafe");
3130 conf->writeEntry(APP_KEY+"document", filename); 3131 conf->writeEntry(APP_KEY+"document", filename);
3131 saveConf(); 3132 saveConf();
3132 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); 3133 QString ti = filename.right (filename.length() - filename.findRev ('/') - 1);
3133 this->setCaption(tr("ZSafe: ") + ti); 3134 this->setCaption(tr("ZSafe: ") + ti);
3134 3135
3135 // clear the password list 3136 // clear the password list
3136 QListViewItem *i; 3137 QListViewItem *i;
3137 QListViewItem *c = NULL; 3138 QListViewItem *c = NULL;
3138 // step through all categories 3139 // step through all categories
3139 for (i = ListView->firstChild(); 3140 for (i = ListView->firstChild();
3140 i != NULL; 3141 i != NULL;
3141 i = i->nextSibling()) 3142 i = i->nextSibling())
3142 { 3143 {
3143 if (c) delete c; // delete the previous category 3144 if (c) delete c; // delete the previous category
3144 3145
3145 c = i; 3146 c = i;
3146 // step through all subitems 3147 // step through all subitems
3147 QListViewItem *si; 3148 QListViewItem *si;
3148 for (si = i->firstChild(); 3149 for (si = i->firstChild();
3149 si != NULL; ) 3150 si != NULL; )
3150 { 3151 {
3151 QListViewItem *_si = si; 3152 QListViewItem *_si = si;
3152 si = si->nextSibling(); 3153 si = si->nextSibling();
3153 i->takeItem(_si); // remove from view list 3154 i->takeItem(_si); // remove from view list
3154 if (_si) delete _si; 3155 if (_si) delete _si;
3155 } 3156 }
3156 } 3157 }
3157 if (c) delete c; // delete the previous category 3158 if (c) delete c; // delete the previous category
3158 categories.clear(); 3159 categories.clear();
3159 3160
3160 m_password = ""; 3161 m_password = "";
3161 selectedItem = NULL; 3162 selectedItem = NULL;
3162 3163
3163 openDocument(filename); 3164 openDocument(filename);
3164} 3165}
3165 3166
3166 3167
3167void ZSafe::ListPressed(int mouse, QListViewItem *item, const QPoint&, int column) { 3168void ZSafe::ListPressed(int mouse, QListViewItem *item, const QPoint&, int column) {
3168 if(item ==0) return; 3169 if(item ==0) return;
3169 switch (mouse) { 3170 switch (mouse) {
3170 case 1: 3171 case 1:
3171 break; 3172 break;
3172 case 2: 3173 case 2:
3173 { 3174 {
3174 QClipboard *cb = QApplication::clipboard(); 3175 QClipboard *cb = QApplication::clipboard();
3175 3176
3176 QIconSet copy_img = Opie::Core::OResource::loadPixmap( "copy", Opie::Core::OResource::SmallIcon ); 3177 QIconSet copy_img = Opie::Core::OResource::loadPixmap( "copy", Opie::Core::OResource::SmallIcon );
3177 QIconSet edit_img = Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ); 3178 QIconSet edit_img = Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon );
3178 QPixmap folder_open_img = Opie::Core::OResource::loadPixmap( "folder_open", Opie::Core::OResource::SmallIcon ); 3179 QPixmap folder_open_img = Opie::Core::OResource::loadPixmap( "folder_open", Opie::Core::OResource::SmallIcon );
3179 QPixmap editdelete_img = Opie::Core::OResource::loadPixmap( "editdelete", Opie::Core::OResource::SmallIcon ); 3180 QPixmap editdelete_img = Opie::Core::OResource::loadPixmap( "editdelete", Opie::Core::OResource::SmallIcon );
3180 3181
3181 QPopupMenu *m = new QPopupMenu(this); 3182 QPopupMenu *m = new QPopupMenu(this);
3182 int copyItem = m->insertItem( copy_img, tr( "Copy to Clipboard" )); 3183 int copyItem = m->insertItem( copy_img, tr( "Copy to Clipboard" ));
3183 int editItem = m->insertItem(edit_img, tr( "Edit" )); 3184 int editItem = m->insertItem(edit_img, tr( "Edit" ));
3184 int showItem = m->insertItem(folder_open_img, tr( "Show Info" )); 3185 int showItem = m->insertItem(folder_open_img, tr( "Show Info" ));
3185 int cancelItem = m->insertItem( editdelete_img, tr( "Cancel" )); 3186 int cancelItem = m->insertItem( editdelete_img, tr( "Cancel" ));
3186 m->setFocus(); 3187 m->setFocus();
3187 int me=m->exec( QPoint( QCursor::pos().x(), QCursor::pos().y() ) ) ; 3188 int me=m->exec( QPoint( QCursor::pos().x(), QCursor::pos().y() ) ) ;
3188 if(me == copyItem) { 3189 if(me == copyItem) {
3189 copyClip( item->text(column) ) ; 3190 copyClip( item->text(column) ) ;
3190 } else if (me == cancelItem) { 3191 } else if (me == cancelItem) {
3191 cb->clear(); 3192 cb->clear();
3192 } else if (me == editItem) { 3193 } else if (me == editItem) {
3193 editPwd(); 3194 editPwd();
3194 } else if (me == showItem) { 3195 } else if (me == showItem) {
3195 showInfo(item); 3196 showInfo(item);
3196 } 3197 }
3197 } 3198 }
3198 break; 3199 break;
3199 }; 3200 };
3200} 3201}
3201 3202
3202void ZSafe::copyClip( const QString &text) { 3203void ZSafe::copyClip( const QString &text) {
3203 QClipboard *cb = QApplication::clipboard(); 3204 QClipboard *cb = QApplication::clipboard();
3204 cb->setText( text); 3205 cb->setText( text);
3205} 3206}
3206 3207
3207 3208
3208QString ZSafe::zsaveDialog() { 3209QString ZSafe::zsaveDialog() {
3209 3210
3210 QString fn; 3211 QString fn;
3211 QMap<QString, QStringList> mimeTypes; 3212 QMap<QString, QStringList> mimeTypes;
3212 mimeTypes.insert(tr("All"), QStringList() ); 3213 mimeTypes.insert(tr("All"), QStringList() );
3213 mimeTypes.insert(tr("Text"), "text/*" ); 3214 mimeTypes.insert(tr("Text"), "text/*" );
3214 fn = OFileDialog::getSaveFileName( OFileSelector::EXTENDED_ALL, 3215 fn = OFileDialog::getSaveFileName( OFileSelector::EXTENDED_ALL,
3215 QDir::homeDirPath() + "/Documents/application/zsafe", 3216 QDir::homeDirPath() + "/Documents/application/zsafe",
3216 QString::null, 3217 QString::null,
3217 mimeTypes, 3218 mimeTypes,
3218 this, 3219 this,
3219 tr ("Export text file")); 3220 tr ("Export text file"));
3220 return fn; 3221 return fn;
3221} 3222}
diff --git a/noncore/comm/keypebble/vncauth.c b/noncore/comm/keypebble/vncauth.c
index 277d145..7de837a 100644
--- a/noncore/comm/keypebble/vncauth.c
+++ b/noncore/comm/keypebble/vncauth.c
@@ -1,160 +1,164 @@
1/* 1/*
2 * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory 2 * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
3 * 3 *
4 * This is free software; you can redistribute it and/or modify 4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This software is distributed in the hope that it will be useful, 9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA. 17 * USA.
18 */ 18 */
19 19
20/* 20/*
21 * vncauth.c - Functions for VNC password management and authentication. 21 * vncauth.c - Functions for VNC password management and authentication.
22 */ 22 */
23 23
24#include <stdio.h> 24#include <stdio.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <sys/types.h> 27#include <sys/types.h>
28#include <sys/stat.h> 28#include <sys/stat.h>
29#include <time.h> 29#include <time.h>
30#include "vncauth.h" 30#include "vncauth.h"
31#include "d3des.h" 31#include "d3des.h"
32 32
33 33
34/* 34/*
35 * We use a fixed key to store passwords, since we assume that our local 35 * We use a fixed key to store passwords, since we assume that our local
36 * file system is secure but nonetheless don't want to store passwords 36 * file system is secure but nonetheless don't want to store passwords
37 * as plaintext. 37 * as plaintext.
38 */ 38 */
39 39
40unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; 40unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7};
41 41
42 42
43/* 43/*
44 * Encrypt a password and store it in a file. Returns 0 if successful, 44 * Encrypt a password and store it in a file. Returns 0 if successful,
45 * 1 if the file could not be written. 45 * 1 if the file could not be written.
46 */ 46 */
47 47
48int 48int
49vncEncryptAndStorePasswd(char *passwd, char *fname) 49vncEncryptAndStorePasswd(char *passwd, char *fname)
50{ 50{
51 FILE *fp; 51 FILE *fp;
52 uint i; 52 uint i;
53 unsigned char encryptedPasswd[8]; 53 unsigned char encryptedPasswd[8];
54 54
55 if ((fp = fopen(fname,"w")) == NULL) return 1; 55 if ((fp = fopen(fname,"w")) == NULL) return 1;
56 56
57 chmod(fname, S_IRUSR|S_IWUSR); 57 chmod(fname, S_IRUSR|S_IWUSR);
58 58
59 /* pad password with nulls */ 59 /* pad password with nulls */
60 60
61 for (i = 0; i < 8; i++) { 61 for (i = 0; i < 8; i++) {
62 if (i < strlen(passwd)) { 62 if (i < strlen(passwd)) {
63 encryptedPasswd[i] = passwd[i]; 63 encryptedPasswd[i] = passwd[i];
64 } else { 64 } else {
65 encryptedPasswd[i] = 0; 65 encryptedPasswd[i] = 0;
66 } 66 }
67 } 67 }
68 68
69 /* Do encryption in-place - this way we overwrite our copy of the plaintext 69 /* Do encryption in-place - this way we overwrite our copy of the plaintext
70 password */ 70 password */
71 71
72 deskey(fixedkey, EN0); 72 deskey(fixedkey, EN0);
73 des(encryptedPasswd, encryptedPasswd); 73 des(encryptedPasswd, encryptedPasswd);
74 74
75 for (i = 0; i < 8; i++) { 75 for (i = 0; i < 8; i++) {
76 putc(encryptedPasswd[i], fp); 76 putc(encryptedPasswd[i], fp);
77 } 77 }
78 78
79 fclose(fp); 79 fclose(fp);
80 return 0; 80 return 0;
81} 81}
82 82
83 83
84/* 84/*
85 * Decrypt a password from a file. Returns a pointer to a newly allocated 85 * Decrypt a password from a file. Returns a pointer to a newly allocated
86 * string containing the password or a null pointer if the password could 86 * string containing the password or a null pointer if the password could
87 * not be retrieved for some reason. 87 * not be retrieved for some reason.
88 */ 88 */
89 89
90char * 90char *
91vncDecryptPasswdFromFile(char *fname) 91vncDecryptPasswdFromFile(char *fname)
92{ 92{
93 FILE *fp; 93 FILE *fp;
94 int i, ch; 94 int i, ch;
95 unsigned char *passwd = (unsigned char *)malloc(9); 95 unsigned char *passwd = (unsigned char *)malloc(9);
96 96
97 if ((fp = fopen(fname,"r")) == NULL) return NULL; 97 if ((fp = fopen(fname,"r")) == NULL) {
98 free(passwd);
99 return NULL;
100 }
98 101
99 for (i = 0; i < 8; i++) { 102 for (i = 0; i < 8; i++) {
100 ch = getc(fp); 103 ch = getc(fp);
101 if (ch == EOF) { 104 if (ch == EOF) {
102 fclose(fp); 105 fclose(fp);
106 free(passwd);
103 return NULL; 107 return NULL;
104 } 108 }
105 passwd[i] = ch; 109 passwd[i] = ch;
106 } 110 }
107 111
108 deskey(fixedkey, DE1); 112 deskey(fixedkey, DE1);
109 des(passwd, passwd); 113 des(passwd, passwd);
110 114
111 passwd[8] = 0; 115 passwd[8] = 0;
112 116
113 return (char *)passwd; 117 return (char *)passwd;
114} 118}
115 119
116 120
117/* 121/*
118 * Generate CHALLENGESIZE random bytes for use in challenge-response 122 * Generate CHALLENGESIZE random bytes for use in challenge-response
119 * authentication. 123 * authentication.
120 */ 124 */
121 125
122void 126void
123vncRandomBytes(unsigned char *bytes) 127vncRandomBytes(unsigned char *bytes)
124{ 128{
125 int i; 129 int i;
126 unsigned int seed = (unsigned int) time(0); 130 unsigned int seed = (unsigned int) time(0);
127 131
128 srandom(seed); 132 srandom(seed);
129 for (i = 0; i < CHALLENGESIZE; i++) { 133 for (i = 0; i < CHALLENGESIZE; i++) {
130 bytes[i] = (unsigned char)(random() & 255); 134 bytes[i] = (unsigned char)(random() & 255);
131 } 135 }
132} 136}
133 137
134 138
135/* 139/*
136 * Encrypt CHALLENGESIZE bytes in memory using a password. 140 * Encrypt CHALLENGESIZE bytes in memory using a password.
137 */ 141 */
138 142
139void 143void
140vncEncryptBytes(unsigned char *bytes, char *passwd) 144vncEncryptBytes(unsigned char *bytes, char *passwd)
141{ 145{
142 unsigned char key[8]; 146 unsigned char key[8];
143 int i; 147 int i;
144 148
145 /* key is simply password padded with nulls */ 149 /* key is simply password padded with nulls */
146 150
147 for (i = 0; i < 8; i++) { 151 for (i = 0; i < 8; i++) {
148 if (i < strlen(passwd)) { 152 if (i < strlen(passwd)) {
149 key[i] = passwd[i]; 153 key[i] = passwd[i];
150 } else { 154 } else {
151 key[i] = 0; 155 key[i] = 0;
152 } 156 }
153 } 157 }
154 158
155 deskey(key, EN0); 159 deskey(key, EN0);
156 160
157 for (i = 0; i < CHALLENGESIZE; i += 8) { 161 for (i = 0; i < CHALLENGESIZE; i += 8) {
158 des(bytes+i, bytes+i); 162 des(bytes+i, bytes+i);
159 } 163 }
160} 164}
diff --git a/noncore/net/ftplib/ftplib.c b/noncore/net/ftplib/ftplib.c
index efcd6f0..addf9d2 100644
--- a/noncore/net/ftplib/ftplib.c
+++ b/noncore/net/ftplib/ftplib.c
@@ -1,1350 +1,1354 @@
1/***************************************************************************/ 1/***************************************************************************/
2/* ftplib.c - callable ftp access routines */ 2/* ftplib.c - callable ftp access routines */
3/* Copyright (C) 1996-2000 Thomas Pfau, pfau@cnj.digex.net */ 3/* Copyright (C) 1996-2000 Thomas Pfau, pfau@cnj.digex.net */
4/* 73 Catherine Street, South Bound Brook, NJ, 08880 */ 4/* 73 Catherine Street, South Bound Brook, NJ, 08880 */
5/* */ 5/* */
6/* This library is free software; you can redistribute it and/or */ 6/* This library is free software; you can redistribute it and/or */
7/* modify it under the terms of the GNU Library General Public */ 7/* modify it under the terms of the GNU Library General Public */
8/* License as published by the Free Software Foundation; either */ 8/* License as published by the Free Software Foundation; either */
9/* version 2 of the License, or (at your option) any later version. */ 9/* version 2 of the License, or (at your option) any later version. */
10/* */ 10/* */
11/* This library is distributed in the hope that it will be useful, */ 11/* This library is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
14/* Library General Public License for more details. */ 14/* Library General Public License for more details. */
15/* */ 15/* */
16/* You should have received a copy of the GNU Library General Public */ 16/* You should have received a copy of the GNU Library General Public */
17/* License along with this progam; if not, write to the */ 17/* License along with this progam; if not, write to the */
18/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ 18/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
19/* Boston, MA 02111-1307, USA. */ 19/* Boston, MA 02111-1307, USA. */
20/* */ 20/* */
21/***************************************************************************/ 21/***************************************************************************/
22// changes made by Lorn Potter <llornkcor@handhelds.org> 22// changes made by Lorn Potter <llornkcor@handhelds.org>
23// 23//
24#if defined(__unix__) || defined(__VMS) 24#if defined(__unix__) || defined(__VMS)
25#include <unistd.h> 25#include <unistd.h>
26#endif 26#endif
27#if defined(_WIN32) 27#if defined(_WIN32)
28#include <windows.h> 28#include <windows.h>
29#endif 29#endif
30 30
31#include <stdio.h> 31#include <stdio.h>
32#include <stdlib.h> 32#include <stdlib.h>
33#include <string.h> 33#include <string.h>
34#include <errno.h> 34#include <errno.h>
35#include <ctype.h> 35#include <ctype.h>
36 36
37#if defined(__unix__) 37#if defined(__unix__)
38 38
39#include <sys/types.h> 39#include <sys/types.h>
40#include <unistd.h> 40#include <unistd.h>
41#include <fcntl.h> 41#include <fcntl.h>
42#include <sys/time.h> 42#include <sys/time.h>
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/socket.h> 44#include <sys/socket.h>
45#include <netinet/in.h> 45#include <netinet/in.h>
46#include <netdb.h> 46#include <netdb.h>
47#include <arpa/inet.h> 47#include <arpa/inet.h>
48 48
49#elif defined(VMS) 49#elif defined(VMS)
50 50
51#include <types.h> 51#include <types.h>
52#include <socket.h> 52#include <socket.h>
53#include <in.h> 53#include <in.h>
54#include <netdb.h> 54#include <netdb.h>
55#include <inet.h> 55#include <inet.h>
56 56
57#elif defined(_WIN32) 57#elif defined(_WIN32)
58 58
59#include <winsock.h> 59#include <winsock.h>
60 60
61#endif 61#endif
62 62
63#define BUILDING_LIBRARY 63#define BUILDING_LIBRARY
64#include "ftplib.h" 64#include "ftplib.h"
65 65
66#if defined(_WIN32) 66#if defined(_WIN32)
67#define SETSOCKOPT_OPTVAL_TYPE (const char *) 67#define SETSOCKOPT_OPTVAL_TYPE (const char *)
68#else 68#else
69#define SETSOCKOPT_OPTVAL_TYPE (void *) 69#define SETSOCKOPT_OPTVAL_TYPE (void *)
70#endif 70#endif
71 71
72#define FTPLIB_BUFSIZ 8192 72#define FTPLIB_BUFSIZ 8192
73#define ACCEPT_TIMEOUT 10 73#define ACCEPT_TIMEOUT 10
74 74
75#define FTPLIB_CONTROL 0 75#define FTPLIB_CONTROL 0
76#define FTPLIB_READ 1 76#define FTPLIB_READ 1
77#define FTPLIB_WRITE 2 77#define FTPLIB_WRITE 2
78 78
79#if !defined FTPLIB_DEFMODE 79#if !defined FTPLIB_DEFMODE
80#define FTPLIB_DEFMODE FTPLIB_PASSIVE 80#define FTPLIB_DEFMODE FTPLIB_PASSIVE
81#endif 81#endif
82 82
83struct NetBuf { 83struct NetBuf {
84 char *cput,*cget; 84 char *cput,*cget;
85 int handle; 85 int handle;
86 int cavail,cleft; 86 int cavail,cleft;
87 char *buf; 87 char *buf;
88 int dir; 88 int dir;
89 netbuf *ctrl; 89 netbuf *ctrl;
90 netbuf *data; 90 netbuf *data;
91 int cmode; 91 int cmode;
92 struct timeval idletime; 92 struct timeval idletime;
93 FtpCallback idlecb; 93 FtpCallback idlecb;
94 void *idlearg; 94 void *idlearg;
95 int xfered; 95 int xfered;
96 int cbbytes; 96 int cbbytes;
97 int xfered1; 97 int xfered1;
98 char response[256]; 98 char response[256];
99}; 99};
100 100
101static char *version = 101static char *version =
102"ftplib Release 3.1-1 9/16/00, copyright 1996-2000 Thomas Pfau"; 102"ftplib Release 3.1-1 9/16/00, copyright 1996-2000 Thomas Pfau";
103 103
104GLOBALDEF int ftplib_debug = 0; 104GLOBALDEF int ftplib_debug = 0;
105 105
106#if defined(__unix__) || defined(VMS) 106#if defined(__unix__) || defined(VMS)
107#define net_read read 107#define net_read read
108#define net_write write 108#define net_write write
109#define net_close close 109#define net_close close
110#elif defined(_WIN32) 110#elif defined(_WIN32)
111#define net_read(x,y,z) recv(x,y,z,0) 111#define net_read(x,y,z) recv(x,y,z,0)
112#define net_write(x,y,z) send(x,y,z,0) 112#define net_write(x,y,z) send(x,y,z,0)
113#define net_close closesocket 113#define net_close closesocket
114#endif 114#endif
115 115
116#if defined(NEED_MEMCCPY) 116#if defined(NEED_MEMCCPY)
117/* 117/*
118 * VAX C does not supply a memccpy routine so I provide my own 118 * VAX C does not supply a memccpy routine so I provide my own
119 */ 119 */
120void *memccpy(void *dest, const void *src, int c, size_t n) 120void *memccpy(void *dest, const void *src, int c, size_t n)
121{ 121{
122 int i=0; 122 int i=0;
123 const unsigned char *ip=src; 123 const unsigned char *ip=src;
124 unsigned char *op=dest; 124 unsigned char *op=dest;
125 125
126 while (i < n) 126 while (i < n)
127 { 127 {
128 if ((*op++ = *ip++) == c) 128 if ((*op++ = *ip++) == c)
129 break; 129 break;
130 i++; 130 i++;
131 } 131 }
132 if (i == n) 132 if (i == n)
133 return NULL; 133 return NULL;
134 return op; 134 return op;
135} 135}
136#endif 136#endif
137#if defined(NEED_STRDUP) 137#if defined(NEED_STRDUP)
138/* 138/*
139 * strdup - return a malloc'ed copy of a string 139 * strdup - return a malloc'ed copy of a string
140 */ 140 */
141char *strdup(const char *src) 141char *strdup(const char *src)
142{ 142{
143 int l = strlen(src) + 1; 143 int l = strlen(src) + 1;
144 char *dst = malloc(l); 144 char *dst = malloc(l);
145 if (dst) 145 if (dst)
146 strcpy(dst,src); 146 strcpy(dst,src);
147 return dst; 147 return dst;
148} 148}
149#endif 149#endif
150 150
151/* 151/*
152 * socket_wait - wait for socket to receive or flush data 152 * socket_wait - wait for socket to receive or flush data
153 * 153 *
154 * return 1 if no user callback, otherwise, return value returned by 154 * return 1 if no user callback, otherwise, return value returned by
155 * user callback 155 * user callback
156 */ 156 */
157static int socket_wait(netbuf *ctl) 157static int socket_wait(netbuf *ctl)
158{ 158{
159 fd_set fd,*rfd = NULL,*wfd = NULL; 159 fd_set fd,*rfd = NULL,*wfd = NULL;
160 struct timeval tv; 160 struct timeval tv;
161 int rv = 0; 161 int rv = 0;
162 if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb == NULL)) 162 if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb == NULL))
163 return 1; 163 return 1;
164 if (ctl->dir == FTPLIB_WRITE) 164 if (ctl->dir == FTPLIB_WRITE)
165 wfd = &fd; 165 wfd = &fd;
166 else 166 else
167 rfd = &fd; 167 rfd = &fd;
168 FD_ZERO(&fd); 168 FD_ZERO(&fd);
169 do 169 do
170 { 170 {
171 FD_SET(ctl->handle,&fd); 171 FD_SET(ctl->handle,&fd);
172 tv = ctl->idletime; 172 tv = ctl->idletime;
173 rv = select(ctl->handle+1, rfd, wfd, NULL, &tv); 173 rv = select(ctl->handle+1, rfd, wfd, NULL, &tv);
174 if (rv == -1) 174 if (rv == -1)
175 { 175 {
176 rv = 0; 176 rv = 0;
177 strncpy(ctl->ctrl->response, strerror(errno), 177 strncpy(ctl->ctrl->response, strerror(errno),
178 sizeof(ctl->ctrl->response)); 178 sizeof(ctl->ctrl->response));
179 break; 179 break;
180 } 180 }
181 else if (rv > 0) 181 else if (rv > 0)
182 { 182 {
183 rv = 1; 183 rv = 1;
184 break; 184 break;
185 } 185 }
186 } 186 }
187 while ((rv = ctl->idlecb(ctl, ctl->xfered, ctl->idlearg))); 187 while ((rv = ctl->idlecb(ctl, ctl->xfered, ctl->idlearg)));
188 return rv; 188 return rv;
189} 189}
190 190
191/* 191/*
192 * read a line of text 192 * read a line of text
193 * 193 *
194 * return -1 on error or bytecount 194 * return -1 on error or bytecount
195 */ 195 */
196static int readline(char *buf,int max,netbuf *ctl) 196static int readline(char *buf,int max,netbuf *ctl)
197{ 197{
198 int x,retval = 0; 198 int x,retval = 0;
199 char *end,*bp=buf; 199 char *end,*bp=buf;
200 int eof = 0; 200 int eof = 0;
201 201
202 if ((ctl->dir != FTPLIB_CONTROL) && (ctl->dir != FTPLIB_READ)) 202 if ((ctl->dir != FTPLIB_CONTROL) && (ctl->dir != FTPLIB_READ))
203 return -1; 203 return -1;
204 if (max == 0) 204 if (max == 0)
205 return 0; 205 return 0;
206 do 206 do
207 { 207 {
208 if (ctl->cavail > 0) 208 if (ctl->cavail > 0)
209 { 209 {
210 x = (max >= ctl->cavail) ? ctl->cavail : max-1; 210 x = (max >= ctl->cavail) ? ctl->cavail : max-1;
211 end = memccpy(bp,ctl->cget,'\n',x); 211 end = memccpy(bp,ctl->cget,'\n',x);
212 if (end != NULL) 212 if (end != NULL)
213 x = end - bp; 213 x = end - bp;
214 retval += x; 214 retval += x;
215 bp += x; 215 bp += x;
216 *bp = '\0'; 216 *bp = '\0';
217 max -= x; 217 max -= x;
218 ctl->cget += x; 218 ctl->cget += x;
219 ctl->cavail -= x; 219 ctl->cavail -= x;
220 if (end != NULL) 220 if (end != NULL)
221 { 221 {
222 bp -= 2; 222 bp -= 2;
223 if (strcmp(bp,"\r\n") == 0) 223 if (strcmp(bp,"\r\n") == 0)
224 { 224 {
225 *bp++ = '\n'; 225 *bp++ = '\n';
226 *bp++ = '\0'; 226 *bp++ = '\0';
227 --retval; 227 --retval;
228 } 228 }
229 break; 229 break;
230 } 230 }
231 } 231 }
232 if (max == 1) 232 if (max == 1)
233 { 233 {
234 *buf = '\0'; 234 *buf = '\0';
235 break; 235 break;
236 } 236 }
237 if (ctl->cput == ctl->cget) 237 if (ctl->cput == ctl->cget)
238 { 238 {
239 ctl->cput = ctl->cget = ctl->buf; 239 ctl->cput = ctl->cget = ctl->buf;
240 ctl->cavail = 0; 240 ctl->cavail = 0;
241 ctl->cleft = FTPLIB_BUFSIZ; 241 ctl->cleft = FTPLIB_BUFSIZ;
242 } 242 }
243 if (eof) 243 if (eof)
244 { 244 {
245 if (retval == 0) 245 if (retval == 0)
246 retval = -1; 246 retval = -1;
247 break; 247 break;
248 } 248 }
249 if (!socket_wait(ctl)) 249 if (!socket_wait(ctl))
250 return retval; 250 return retval;
251 if ((x = net_read(ctl->handle,ctl->cput,ctl->cleft)) == -1) 251 if ((x = net_read(ctl->handle,ctl->cput,ctl->cleft)) == -1)
252 { 252 {
253 perror("read"); 253 perror("read");
254 retval = -1; 254 retval = -1;
255 break; 255 break;
256 } 256 }
257 if (x == 0) 257 if (x == 0)
258 eof = 1; 258 eof = 1;
259 ctl->cleft -= x; 259 ctl->cleft -= x;
260 ctl->cavail += x; 260 ctl->cavail += x;
261 ctl->cput += x; 261 ctl->cput += x;
262 } 262 }
263 while (1); 263 while (1);
264 return retval; 264 return retval;
265} 265}
266 266
267/* 267/*
268 * write lines of text 268 * write lines of text
269 * 269 *
270 * return -1 on error or bytecount 270 * return -1 on error or bytecount
271 */ 271 */
272static int writeline(char *buf, int len, netbuf *nData) 272static int writeline(char *buf, int len, netbuf *nData)
273{ 273{
274 int x, nb=0, w; 274 int x, nb=0, w;
275 char *ubp = buf, *nbp; 275 char *ubp = buf, *nbp;
276 char lc=0; 276 char lc=0;
277 277
278 if (nData->dir != FTPLIB_WRITE) 278 if (nData->dir != FTPLIB_WRITE)
279 return -1; 279 return -1;
280 nbp = nData->buf; 280 nbp = nData->buf;
281 for (x=0; x < len; x++) 281 for (x=0; x < len; x++)
282 { 282 {
283 if ((*ubp == '\n') && (lc != '\r')) 283 if ((*ubp == '\n') && (lc != '\r'))
284 { 284 {
285 if (nb == FTPLIB_BUFSIZ) 285 if (nb == FTPLIB_BUFSIZ)
286 { 286 {
287 if (!socket_wait(nData)) 287 if (!socket_wait(nData))
288 return x; 288 return x;
289 w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); 289 w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ);
290 if (w != FTPLIB_BUFSIZ) 290 if (w != FTPLIB_BUFSIZ)
291 { 291 {
292 printf("net_write(1) returned %d, errno = %d\n", w, errno); 292 printf("net_write(1) returned %d, errno = %d\n", w, errno);
293 return(-1); 293 return(-1);
294 } 294 }
295 nb = 0; 295 nb = 0;
296 } 296 }
297 nbp[nb++] = '\r'; 297 nbp[nb++] = '\r';
298 } 298 }
299 if (nb == FTPLIB_BUFSIZ) 299 if (nb == FTPLIB_BUFSIZ)
300 { 300 {
301 if (!socket_wait(nData)) 301 if (!socket_wait(nData))
302 return x; 302 return x;
303 w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); 303 w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ);
304 if (w != FTPLIB_BUFSIZ) 304 if (w != FTPLIB_BUFSIZ)
305 { 305 {
306 printf("net_write(2) returned %d, errno = %d\n", w, errno); 306 printf("net_write(2) returned %d, errno = %d\n", w, errno);
307 return(-1); 307 return(-1);
308 } 308 }
309 nb = 0; 309 nb = 0;
310 } 310 }
311 nbp[nb++] = lc = *ubp++; 311 nbp[nb++] = lc = *ubp++;
312 } 312 }
313 if (nb) 313 if (nb)
314 { 314 {
315 if (!socket_wait(nData)) 315 if (!socket_wait(nData))
316 return x; 316 return x;
317 w = net_write(nData->handle, nbp, nb); 317 w = net_write(nData->handle, nbp, nb);
318 if (w != nb) 318 if (w != nb)
319 { 319 {
320 printf("net_write(3) returned %d, errno = %d\n", w, errno); 320 printf("net_write(3) returned %d, errno = %d\n", w, errno);
321 return(-1); 321 return(-1);
322 } 322 }
323 } 323 }
324 return len; 324 return len;
325} 325}
326 326
327/* 327/*
328 * read a response from the server 328 * read a response from the server
329 * 329 *
330 * return 0 if first char doesn't match 330 * return 0 if first char doesn't match
331 * return 1 if first char matches 331 * return 1 if first char matches
332 */ 332 */
333static int readresp(char c, netbuf *nControl) 333static int readresp(char c, netbuf *nControl)
334{ 334{
335 char match[5]; 335 char match[5];
336 if (readline(nControl->response,256,nControl) == -1) 336 if (readline(nControl->response,256,nControl) == -1)
337 { 337 {
338 perror("Control socket read failed"); 338 perror("Control socket read failed");
339 return 0; 339 return 0;
340 } 340 }
341 if (ftplib_debug > 1) 341 if (ftplib_debug > 1)
342 fprintf(stderr,"%s",nControl->response); 342 fprintf(stderr,"%s",nControl->response);
343 if (nControl->response[3] == '-') 343 if (nControl->response[3] == '-')
344 { 344 {
345 strncpy(match,nControl->response,3); 345 strncpy(match,nControl->response,3);
346 match[3] = ' '; 346 match[3] = ' ';
347 match[4] = '\0'; 347 match[4] = '\0';
348 do 348 do
349 { 349 {
350 if (readline(nControl->response,256,nControl) == -1) 350 if (readline(nControl->response,256,nControl) == -1)
351 { 351 {
352 perror("Control socket read failed"); 352 perror("Control socket read failed");
353 return 0; 353 return 0;
354 } 354 }
355 if (ftplib_debug > 1) 355 if (ftplib_debug > 1)
356 fprintf(stderr,"%s",nControl->response); 356 fprintf(stderr,"%s",nControl->response);
357 } 357 }
358 while (strncmp(nControl->response,match,4)); 358 while (strncmp(nControl->response,match,4));
359 } 359 }
360 if (nControl->response[0] == c) 360 if (nControl->response[0] == c)
361 return 1; 361 return 1;
362 return 0; 362 return 0;
363} 363}
364 364
365/* 365/*
366 * FtpInit for stupid operating systems that require it (Windows NT) 366 * FtpInit for stupid operating systems that require it (Windows NT)
367 */ 367 */
368GLOBALDEF void FtpInit(void) 368GLOBALDEF void FtpInit(void)
369{ 369{
370#if defined(_WIN32) 370#if defined(_WIN32)
371 WORD wVersionRequested; 371 WORD wVersionRequested;
372 WSADATA wsadata; 372 WSADATA wsadata;
373 int err; 373 int err;
374 wVersionRequested = MAKEWORD(1,1); 374 wVersionRequested = MAKEWORD(1,1);
375 if ((err = WSAStartup(wVersionRequested,&wsadata)) != 0) 375 if ((err = WSAStartup(wVersionRequested,&wsadata)) != 0)
376 fprintf(stderr,"Network failed to start: %d\n",err); 376 fprintf(stderr,"Network failed to start: %d\n",err);
377#endif 377#endif
378} 378}
379 379
380/* 380/*
381 * FtpLastResponse - return a pointer to the last response received 381 * FtpLastResponse - return a pointer to the last response received
382 */ 382 */
383GLOBALDEF char *FtpLastResponse(netbuf *nControl) 383GLOBALDEF char *FtpLastResponse(netbuf *nControl)
384{ 384{
385 if ((nControl) && (nControl->dir == FTPLIB_CONTROL)) 385 if ((nControl) && (nControl->dir == FTPLIB_CONTROL))
386 return nControl->response; 386 return nControl->response;
387 return NULL; 387 return NULL;
388} 388}
389 389
390/* 390/*
391 * FtpConnect - connect to remote server 391 * FtpConnect - connect to remote server
392 * 392 *
393 * return 1 if connected, 0 if not 393 * return 1 if connected, 0 if not
394 */ 394 */
395GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) 395GLOBALDEF int FtpConnect(const char *host, netbuf **nControl)
396{ 396{
397 int sControl, stat, flags, oldflags; 397 int sControl, stat, flags, oldflags;
398 struct sockaddr_in sin; 398 struct sockaddr_in sin;
399 struct hostent *phe; 399 struct hostent *phe;
400 struct servent *pse; 400 struct servent *pse;
401 int on=1; 401 int on=1;
402 netbuf *ctrl; 402 netbuf *ctrl;
403 char *lhost; 403 char *lhost;
404 char *pnum; 404 char *pnum;
405 struct timeval tv; 405 struct timeval tv;
406 fd_set wr; 406 fd_set wr;
407 407
408 memset(&sin,0,sizeof(sin)); 408 memset(&sin,0,sizeof(sin));
409 sin.sin_family = AF_INET; 409 sin.sin_family = AF_INET;
410 lhost = strdup(host); 410 lhost = strdup(host);
411 pnum = strchr(lhost,':'); 411 pnum = strchr(lhost,':');
412 if (pnum == NULL) 412 if (pnum == NULL)
413 { 413 {
414#if defined(VMS) 414#if defined(VMS)
415 sin.sin_port = htons(21); 415 sin.sin_port = htons(21);
416#else 416#else
417 if ((pse = getservbyname("ftp","tcp")) == NULL) 417 if ((pse = getservbyname("ftp","tcp")) == NULL)
418 { 418 {
419 perror("getservbyname"); 419 perror("getservbyname");
420 return 0; 420 return 0;
421 } 421 }
422 sin.sin_port = pse->s_port; 422 sin.sin_port = pse->s_port;
423#endif 423#endif
424 } 424 }
425 else 425 else
426 { 426 {
427 *pnum++ = '\0'; 427 *pnum++ = '\0';
428 if (isdigit(*pnum)) 428 if (isdigit(*pnum))
429 sin.sin_port = htons(atoi(pnum)); 429 sin.sin_port = htons(atoi(pnum));
430 else 430 else
431 { 431 {
432 pse = getservbyname(pnum,"tcp"); 432 pse = getservbyname(pnum,"tcp");
433 sin.sin_port = pse->s_port; 433 sin.sin_port = pse->s_port;
434 } 434 }
435 } 435 }
436 if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) 436 if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1)
437 { 437 {
438 if ((phe = gethostbyname(lhost)) == NULL) 438 if ((phe = gethostbyname(lhost)) == NULL)
439 { 439 {
440 perror("gethostbyname"); 440 perror("gethostbyname");
441 return 0; 441 return 0;
442 } 442 }
443 443
444 memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); 444 memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);
445 445
446 } 446 }
447 free(lhost); 447 free(lhost);
448 448
449 sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 449 sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
450 if (sControl == -1) 450 if (sControl == -1)
451 { 451 {
452 perror("socket"); 452 perror("socket");
453 return 0; 453 return 0;
454 } 454 }
455 455
456 if ( setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, 456 if ( setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR,
457 SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) 457 SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1)
458 { 458 {
459 perror("setsockopt"); 459 perror("setsockopt");
460 net_close(sControl); 460 net_close(sControl);
461 return 0; 461 return 0;
462 } 462 }
463 463
464 //set nonblocking for connection timeout 464 //set nonblocking for connection timeout
465 flags = fcntl( sControl, F_GETFL,0); 465 flags = fcntl( sControl, F_GETFL,0);
466 oldflags=flags; 466 oldflags=flags;
467 fcntl( sControl, F_SETFL, O_NONBLOCK|flags); 467 fcntl( sControl, F_SETFL, O_NONBLOCK|flags);
468 468
469 stat=connect( sControl, (struct sockaddr *)&sin, sizeof(sin)); 469 stat=connect( sControl, (struct sockaddr *)&sin, sizeof(sin));
470 if (stat < 0) 470 if (stat < 0)
471 { 471 {
472 if (errno != EWOULDBLOCK && errno != EINPROGRESS) 472 if (errno != EWOULDBLOCK && errno != EINPROGRESS)
473 { 473 {
474 perror("connect"); 474 perror("connect");
475 net_close(sControl); 475 net_close(sControl);
476 return 0; 476 return 0;
477 } 477 }
478 } 478 }
479 479
480 FD_ZERO(&wr); 480 FD_ZERO(&wr);
481 FD_SET( sControl, &wr); 481 FD_SET( sControl, &wr);
482 482
483 tv.tv_sec = ACCEPT_TIMEOUT; 483 tv.tv_sec = ACCEPT_TIMEOUT;
484 tv.tv_usec = 0; 484 tv.tv_usec = 0;
485 485
486 stat = select(sControl+1, 0, &wr, 0, &tv); 486 stat = select(sControl+1, 0, &wr, 0, &tv);
487 487
488 if (stat < 1) 488 if (stat < 1)
489 { 489 {
490 // time out has expired, 490 // time out has expired,
491 // or an error has ocurred 491 // or an error has ocurred
492 perror("timeout"); 492 perror("timeout");
493 net_close(sControl); 493 net_close(sControl);
494 return 0; 494 return 0;
495 } 495 }
496 496
497 printf("connected\n"); 497 printf("connected\n");
498 498
499 //set original flags 499 //set original flags
500 fcntl( sControl, F_SETFL, oldflags); 500 fcntl( sControl, F_SETFL, oldflags);
501 501
502 ctrl = calloc(1,sizeof(netbuf)); 502 ctrl = calloc(1,sizeof(netbuf));
503 if (ctrl == NULL) 503 if (ctrl == NULL)
504 { 504 {
505 perror("calloc"); 505 perror("calloc");
506 net_close(sControl); 506 net_close(sControl);
507 return 0; 507 return 0;
508 } 508 }
509 ctrl->buf = malloc(FTPLIB_BUFSIZ); 509 ctrl->buf = malloc(FTPLIB_BUFSIZ);
510 if (ctrl->buf == NULL) 510 if (ctrl->buf == NULL)
511 { 511 {
512 perror("calloc"); 512 perror("calloc");
513 net_close(sControl); 513 net_close(sControl);
514 free(ctrl); 514 free(ctrl);
515 return 0; 515 return 0;
516 } 516 }
517 ctrl->handle = sControl; 517 ctrl->handle = sControl;
518 ctrl->dir = FTPLIB_CONTROL; 518 ctrl->dir = FTPLIB_CONTROL;
519 ctrl->ctrl = NULL; 519 ctrl->ctrl = NULL;
520 ctrl->cmode = FTPLIB_DEFMODE; 520 ctrl->cmode = FTPLIB_DEFMODE;
521 ctrl->idlecb = NULL; 521 ctrl->idlecb = NULL;
522 ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; 522 ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0;
523 ctrl->idlearg = NULL; 523 ctrl->idlearg = NULL;
524 ctrl->xfered = 0; 524 ctrl->xfered = 0;
525 ctrl->xfered1 = 0; 525 ctrl->xfered1 = 0;
526 ctrl->cbbytes = 0; 526 ctrl->cbbytes = 0;
527 if (readresp('2', ctrl) == 0) 527 if (readresp('2', ctrl) == 0)
528 { 528 {
529 net_close(sControl); 529 net_close(sControl);
530 free(ctrl->buf); 530 free(ctrl->buf);
531 free(ctrl); 531 free(ctrl);
532 return 0; 532 return 0;
533 } 533 }
534 *nControl = ctrl; 534 *nControl = ctrl;
535 return 1; 535 return 1;
536} 536}
537 537
538/* 538/*
539 * FtpOptions - change connection options 539 * FtpOptions - change connection options
540 * 540 *
541 * returns 1 if successful, 0 on error 541 * returns 1 if successful, 0 on error
542 */ 542 */
543GLOBALDEF int FtpOptions(int opt, long val, netbuf *nControl) 543GLOBALDEF int FtpOptions(int opt, long val, netbuf *nControl)
544{ 544{
545 int v,rv=0; 545 int v,rv=0;
546 switch (opt) 546 switch (opt)
547 { 547 {
548 case FTPLIB_CONNMODE: 548 case FTPLIB_CONNMODE:
549 v = (int) val; 549 v = (int) val;
550 if ((v == FTPLIB_PASSIVE) || (v == FTPLIB_PORT)) 550 if ((v == FTPLIB_PASSIVE) || (v == FTPLIB_PORT))
551 { 551 {
552 nControl->cmode = v; 552 nControl->cmode = v;
553 rv = 1; 553 rv = 1;
554 } 554 }
555 break; 555 break;
556 case FTPLIB_CALLBACK: 556 case FTPLIB_CALLBACK:
557 nControl->idlecb = (FtpCallback) val; 557 nControl->idlecb = (FtpCallback) val;
558 rv = 1; 558 rv = 1;
559 break; 559 break;
560 case FTPLIB_IDLETIME: 560 case FTPLIB_IDLETIME:
561 v = (int) val; 561 v = (int) val;
562 rv = 1; 562 rv = 1;
563 nControl->idletime.tv_sec = v / 1000; 563 nControl->idletime.tv_sec = v / 1000;
564 nControl->idletime.tv_usec = (v % 1000) * 1000; 564 nControl->idletime.tv_usec = (v % 1000) * 1000;
565 break; 565 break;
566 case FTPLIB_CALLBACKARG: 566 case FTPLIB_CALLBACKARG:
567 rv = 1; 567 rv = 1;
568 nControl->idlearg = (void *) val; 568 nControl->idlearg = (void *) val;
569 break; 569 break;
570 case FTPLIB_CALLBACKBYTES: 570 case FTPLIB_CALLBACKBYTES:
571 rv = 1; 571 rv = 1;
572 nControl->cbbytes = (int) val; 572 nControl->cbbytes = (int) val;
573 break; 573 break;
574 } 574 }
575 return rv; 575 return rv;
576} 576}
577 577
578/* 578/*
579 * FtpSendCmd - send a command and wait for expected response 579 * FtpSendCmd - send a command and wait for expected response
580 * 580 *
581 * return 1 if proper response received, 0 otherwise 581 * return 1 if proper response received, 0 otherwise
582 */ 582 */
583static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl) 583static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl)
584{ 584{
585 char buf[256]; 585 char buf[256];
586 if (nControl->dir != FTPLIB_CONTROL) 586 if (nControl->dir != FTPLIB_CONTROL)
587 return 0; 587 return 0;
588 if (ftplib_debug > 2) 588 if (ftplib_debug > 2)
589 fprintf(stderr,"%s\n",cmd); 589 fprintf(stderr,"%s\n",cmd);
590 if ((strlen(cmd) + 3) > sizeof(buf)) 590 if ((strlen(cmd) + 3) > sizeof(buf))
591 return 0; 591 return 0;
592 sprintf(buf,"%s\r\n",cmd); 592 sprintf(buf,"%s\r\n",cmd);
593 if (net_write(nControl->handle,buf,strlen(buf)) <= 0) 593 if (net_write(nControl->handle,buf,strlen(buf)) <= 0)
594 { 594 {
595 perror("write"); 595 perror("write");
596 return 0; 596 return 0;
597 } 597 }
598 return readresp(expresp, nControl); 598 return readresp(expresp, nControl);
599} 599}
600 600
601/* 601/*
602 * FtpLogin - log in to remote server 602 * FtpLogin - log in to remote server
603 * 603 *
604 * return 1 if logged in, 0 otherwise 604 * return 1 if logged in, 0 otherwise
605 */ 605 */
606GLOBALDEF int FtpLogin(const char *user, const char *pass, netbuf *nControl) 606GLOBALDEF int FtpLogin(const char *user, const char *pass, netbuf *nControl)
607{ 607{
608 char tempbuf[64]; 608 char tempbuf[64];
609 609
610 if (((strlen(user) + 7) > sizeof(tempbuf)) || 610 if (((strlen(user) + 7) > sizeof(tempbuf)) ||
611 ((strlen(pass) + 7) > sizeof(tempbuf))) 611 ((strlen(pass) + 7) > sizeof(tempbuf)))
612 return 0; 612 return 0;
613 sprintf(tempbuf,"USER %s",user); 613 sprintf(tempbuf,"USER %s",user);
614 if (!FtpSendCmd(tempbuf,'3',nControl)) 614 if (!FtpSendCmd(tempbuf,'3',nControl))
615 { 615 {
616 if (nControl->response[0] == '2') 616 if (nControl->response[0] == '2')
617 return 1; 617 return 1;
618 return 0; 618 return 0;
619 } 619 }
620 sprintf(tempbuf,"PASS %s",pass); 620 sprintf(tempbuf,"PASS %s",pass);
621 return FtpSendCmd(tempbuf,'2',nControl); 621 return FtpSendCmd(tempbuf,'2',nControl);
622} 622}
623 623
624/* 624/*
625 * FtpOpenPort - set up data connection 625 * FtpOpenPort - set up data connection
626 * 626 *
627 * return 1 if successful, 0 otherwise 627 * return 1 if successful, 0 otherwise
628 */ 628 */
629static int FtpOpenPort(netbuf *nControl, netbuf **nData, int mode, int dir) 629static int FtpOpenPort(netbuf *nControl, netbuf **nData, int mode, int dir)
630{ 630{
631 int sData; 631 int sData;
632 union { 632 union {
633 struct sockaddr sa; 633 struct sockaddr sa;
634 struct sockaddr_in in; 634 struct sockaddr_in in;
635 } sin; 635 } sin;
636 struct linger lng = { 0, 0 }; 636 struct linger lng = { 0, 0 };
637 unsigned int l; 637 unsigned int l;
638 int on=1; 638 int on=1;
639 netbuf *ctrl; 639 netbuf *ctrl;
640 char *cp; 640 char *cp;
641 unsigned int v[6]; 641 unsigned int v[6];
642 char buf[256]; 642 char buf[256];
643 643
644 if (nControl->dir != FTPLIB_CONTROL) 644 if (nControl->dir != FTPLIB_CONTROL)
645 return -1; 645 return -1;
646 if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE)) 646 if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE))
647 { 647 {
648 sprintf(nControl->response, "Invalid direction %d\n", dir); 648 sprintf(nControl->response, "Invalid direction %d\n", dir);
649 return -1; 649 return -1;
650 } 650 }
651 if ((mode != FTPLIB_ASCII) && (mode != FTPLIB_IMAGE)) 651 if ((mode != FTPLIB_ASCII) && (mode != FTPLIB_IMAGE))
652 { 652 {
653 sprintf(nControl->response, "Invalid mode %c\n", mode); 653 sprintf(nControl->response, "Invalid mode %c\n", mode);
654 return -1; 654 return -1;
655 } 655 }
656 l = sizeof(sin); 656 l = sizeof(sin);
657 if (nControl->cmode == FTPLIB_PASSIVE) 657 if (nControl->cmode == FTPLIB_PASSIVE)
658 { 658 {
659 memset(&sin, 0, l); 659 memset(&sin, 0, l);
660 sin.in.sin_family = AF_INET; 660 sin.in.sin_family = AF_INET;
661 if (!FtpSendCmd("PASV",'2',nControl)) 661 if (!FtpSendCmd("PASV",'2',nControl))
662 return -1; 662 return -1;
663 cp = strchr(nControl->response,'('); 663 cp = strchr(nControl->response,'(');
664 if (cp == NULL) 664 if (cp == NULL)
665 return -1; 665 return -1;
666 cp++; 666 cp++;
667 sscanf(cp,"%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]); 667 sscanf(cp,"%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]);
668 sin.sa.sa_data[2] = v[2]; 668 sin.sa.sa_data[2] = v[2];
669 sin.sa.sa_data[3] = v[3]; 669 sin.sa.sa_data[3] = v[3];
670 sin.sa.sa_data[4] = v[4]; 670 sin.sa.sa_data[4] = v[4];
671 sin.sa.sa_data[5] = v[5]; 671 sin.sa.sa_data[5] = v[5];
672 sin.sa.sa_data[0] = v[0]; 672 sin.sa.sa_data[0] = v[0];
673 sin.sa.sa_data[1] = v[1]; 673 sin.sa.sa_data[1] = v[1];
674 } 674 }
675 else 675 else
676 { 676 {
677 if (getsockname(nControl->handle, &sin.sa, &l) < 0) 677 if (getsockname(nControl->handle, &sin.sa, &l) < 0)
678 { 678 {
679 perror("getsockname"); 679 perror("getsockname");
680 return 0; 680 return 0;
681 } 681 }
682 } 682 }
683 sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); 683 sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
684 if (sData == -1) 684 if (sData == -1)
685 { 685 {
686 perror("socket"); 686 perror("socket");
687 return -1; 687 return -1;
688 } 688 }
689 if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR, 689 if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR,
690 SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1) 690 SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1)
691 { 691 {
692 perror("setsockopt"); 692 perror("setsockopt");
693 net_close(sData); 693 net_close(sData);
694 return -1; 694 return -1;
695 } 695 }
696 if (setsockopt(sData,SOL_SOCKET,SO_LINGER, 696 if (setsockopt(sData,SOL_SOCKET,SO_LINGER,
697 SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1) 697 SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1)
698 { 698 {
699 perror("setsockopt"); 699 perror("setsockopt");
700 net_close(sData); 700 net_close(sData);
701 return -1; 701 return -1;
702 } 702 }
703 if (nControl->cmode == FTPLIB_PASSIVE) 703 if (nControl->cmode == FTPLIB_PASSIVE)
704 { 704 {
705 if (connect(sData, &sin.sa, sizeof(sin.sa)) == -1) 705 if (connect(sData, &sin.sa, sizeof(sin.sa)) == -1)
706 { 706 {
707 perror("connect"); 707 perror("connect");
708 net_close(sData); 708 net_close(sData);
709 return -1; 709 return -1;
710 } 710 }
711 } 711 }
712 else 712 else
713 { 713 {
714 sin.in.sin_port = 0; 714 sin.in.sin_port = 0;
715 if (bind(sData, &sin.sa, sizeof(sin)) == -1) 715 if (bind(sData, &sin.sa, sizeof(sin)) == -1)
716 { 716 {
717 perror("bind"); 717 perror("bind");
718 net_close(sData); 718 net_close(sData);
719 return 0; 719 return 0;
720 } 720 }
721 if (listen(sData, 1) < 0) 721 if (listen(sData, 1) < 0)
722 { 722 {
723 perror("listen"); 723 perror("listen");
724 net_close(sData); 724 net_close(sData);
725 return 0; 725 return 0;
726 } 726 }
727 if (getsockname(sData, &sin.sa, &l) < 0) 727 if (getsockname(sData, &sin.sa, &l) < 0)
728 return 0; 728 return 0;
729 sprintf(buf, "PORT %d,%d,%d,%d,%d,%d", 729 sprintf(buf, "PORT %d,%d,%d,%d,%d,%d",
730 (unsigned char) sin.sa.sa_data[2], 730 (unsigned char) sin.sa.sa_data[2],
731 (unsigned char) sin.sa.sa_data[3], 731 (unsigned char) sin.sa.sa_data[3],
732 (unsigned char) sin.sa.sa_data[4], 732 (unsigned char) sin.sa.sa_data[4],
733 (unsigned char) sin.sa.sa_data[5], 733 (unsigned char) sin.sa.sa_data[5],
734 (unsigned char) sin.sa.sa_data[0], 734 (unsigned char) sin.sa.sa_data[0],
735 (unsigned char) sin.sa.sa_data[1]); 735 (unsigned char) sin.sa.sa_data[1]);
736 if (!FtpSendCmd(buf,'2',nControl)) 736 if (!FtpSendCmd(buf,'2',nControl))
737 { 737 {
738 net_close(sData); 738 net_close(sData);
739 return 0; 739 return 0;
740 } 740 }
741 } 741 }
742 ctrl = calloc(1,sizeof(netbuf)); 742 ctrl = calloc(1,sizeof(netbuf));
743 if (ctrl == NULL) 743 if (ctrl == NULL)
744 { 744 {
745 perror("calloc"); 745 perror("calloc");
746 net_close(sData); 746 net_close(sData);
747 return -1; 747 return -1;
748 } 748 }
749 if ((mode == 'A') && ((ctrl->buf = malloc(FTPLIB_BUFSIZ)) == NULL)) 749 if ((mode == 'A') && ((ctrl->buf = malloc(FTPLIB_BUFSIZ)) == NULL))
750 { 750 {
751 perror("calloc"); 751 perror("calloc");
752 net_close(sData); 752 net_close(sData);
753 free(ctrl); 753 free(ctrl);
754 return -1; 754 return -1;
755 } 755 }
756 ctrl->handle = sData; 756 ctrl->handle = sData;
757 ctrl->dir = dir; 757 ctrl->dir = dir;
758 ctrl->idletime = nControl->idletime; 758 ctrl->idletime = nControl->idletime;
759 ctrl->idlearg = nControl->idlearg; 759 ctrl->idlearg = nControl->idlearg;
760 ctrl->xfered = 0; 760 ctrl->xfered = 0;
761 ctrl->xfered1 = 0; 761 ctrl->xfered1 = 0;
762 ctrl->cbbytes = nControl->cbbytes; 762 ctrl->cbbytes = nControl->cbbytes;
763 if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec || ctrl->cbbytes) 763 if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec || ctrl->cbbytes)
764 ctrl->idlecb = nControl->idlecb; 764 ctrl->idlecb = nControl->idlecb;
765 else 765 else
766 ctrl->idlecb = NULL; 766 ctrl->idlecb = NULL;
767 *nData = ctrl; 767 *nData = ctrl;
768 return 1; 768 return 1;
769} 769}
770 770
771/* 771/*
772 * FtpAcceptConnection - accept connection from server 772 * FtpAcceptConnection - accept connection from server
773 * 773 *
774 * return 1 if successful, 0 otherwise 774 * return 1 if successful, 0 otherwise
775 */ 775 */
776static int FtpAcceptConnection(netbuf *nData, netbuf *nControl) 776static int FtpAcceptConnection(netbuf *nData, netbuf *nControl)
777{ 777{
778 int sData; 778 int sData;
779 struct sockaddr addr; 779 struct sockaddr addr;
780 unsigned int l; 780 unsigned int l;
781 int i; 781 int i;
782 struct timeval tv; 782 struct timeval tv;
783 fd_set mask; 783 fd_set mask;
784 int rv; 784 int rv;
785 785
786 FD_ZERO(&mask); 786 FD_ZERO(&mask);
787 FD_SET(nControl->handle, &mask); 787 FD_SET(nControl->handle, &mask);
788 FD_SET(nData->handle, &mask); 788 FD_SET(nData->handle, &mask);
789 tv.tv_usec = 0; 789 tv.tv_usec = 0;
790 tv.tv_sec = ACCEPT_TIMEOUT; 790 tv.tv_sec = ACCEPT_TIMEOUT;
791 printf("<<<<<<<<<<<<<<<<%d\n",ACCEPT_TIMEOUT); 791 printf("<<<<<<<<<<<<<<<<%d\n",ACCEPT_TIMEOUT);
792 i = nControl->handle; 792 i = nControl->handle;
793 if (i < nData->handle) 793 if (i < nData->handle)
794 i = nData->handle; 794 i = nData->handle;
795 i = select(i+1, &mask, NULL, NULL, &tv); 795 i = select(i+1, &mask, NULL, NULL, &tv);
796 if (i == -1) 796 if (i == -1)
797 { 797 {
798 strncpy(nControl->response, strerror(errno), 798 strncpy(nControl->response, strerror(errno),
799 sizeof(nControl->response)); 799 sizeof(nControl->response));
800 net_close(nData->handle); 800 net_close(nData->handle);
801 nData->handle = 0; 801 nData->handle = 0;
802 rv = 0; 802 rv = 0;
803 } 803 }
804 else if (i == 0) 804 else if (i == 0)
805 { 805 {
806 strcpy(nControl->response, "timed out waiting for connection"); 806 strcpy(nControl->response, "timed out waiting for connection");
807 net_close(nData->handle); 807 net_close(nData->handle);
808 nData->handle = 0; 808 nData->handle = 0;
809 rv = 0; 809 rv = 0;
810 } 810 }
811 else 811 else
812 { 812 {
813 if (FD_ISSET(nData->handle, &mask)) 813 if (FD_ISSET(nData->handle, &mask))
814 { 814 {
815 l = sizeof(addr); 815 l = sizeof(addr);
816 sData = accept(nData->handle, &addr, &l); 816 sData = accept(nData->handle, &addr, &l);
817 i = errno; 817 i = errno;
818 net_close(nData->handle); 818 net_close(nData->handle);
819 if (sData > 0) 819 if (sData > 0)
820 { 820 {
821 rv = 1; 821 rv = 1;
822 nData->handle = sData; 822 nData->handle = sData;
823 } 823 }
824 else 824 else
825 { 825 {
826 strncpy(nControl->response, strerror(i), 826 strncpy(nControl->response, strerror(i),
827 sizeof(nControl->response)); 827 sizeof(nControl->response));
828 nData->handle = 0; 828 nData->handle = 0;
829 rv = 0; 829 rv = 0;
830 } 830 }
831 } 831 }
832 else if (FD_ISSET(nControl->handle, &mask)) 832 else if (FD_ISSET(nControl->handle, &mask))
833 { 833 {
834 net_close(nData->handle); 834 net_close(nData->handle);
835 nData->handle = 0; 835 nData->handle = 0;
836 readresp('2', nControl); 836 readresp('2', nControl);
837 rv = 0; 837 rv = 0;
838 } 838 }
839 } 839 }
840 return rv; 840 return rv;
841} 841}
842 842
843/* 843/*
844 * FtpAccess - return a handle for a data stream 844 * FtpAccess - return a handle for a data stream
845 * 845 *
846 * return 1 if successful, 0 otherwise 846 * return 1 if successful, 0 otherwise
847 */ 847 */
848GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, 848GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
849 netbuf **nData) 849 netbuf **nData)
850{ 850{
851 char buf[256]; 851 char buf[256];
852 int dir; 852 int dir;
853 if ((path == NULL) && 853 if ((path == NULL) &&
854 ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) 854 ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ)))
855 { 855 {
856 sprintf(nControl->response, 856 sprintf(nControl->response,
857 "Missing path argument for file transfer\n"); 857 "Missing path argument for file transfer\n");
858 return 0; 858 return 0;
859 } 859 }
860 sprintf(buf, "TYPE %c", mode); 860 sprintf(buf, "TYPE %c", mode);
861 if (!FtpSendCmd(buf, '2', nControl)) 861 if (!FtpSendCmd(buf, '2', nControl))
862 return 0; 862 return 0;
863 switch (typ) 863 switch (typ)
864 { 864 {
865 case FTPLIB_DIR: 865 case FTPLIB_DIR:
866 strcpy(buf,"NLST"); 866 strcpy(buf,"NLST");
867 dir = FTPLIB_READ; 867 dir = FTPLIB_READ;
868 break; 868 break;
869 case FTPLIB_DIR_VERBOSE: 869 case FTPLIB_DIR_VERBOSE:
870 strcpy(buf,"LIST"); 870 strcpy(buf,"LIST");
871 dir = FTPLIB_READ; 871 dir = FTPLIB_READ;
872 break; 872 break;
873 case FTPLIB_FILE_READ: 873 case FTPLIB_FILE_READ:
874 strcpy(buf,"RETR"); 874 strcpy(buf,"RETR");
875 dir = FTPLIB_READ; 875 dir = FTPLIB_READ;
876 break; 876 break;
877 case FTPLIB_FILE_WRITE: 877 case FTPLIB_FILE_WRITE:
878 strcpy(buf,"STOR"); 878 strcpy(buf,"STOR");
879 dir = FTPLIB_WRITE; 879 dir = FTPLIB_WRITE;
880 break; 880 break;
881 default: 881 default:
882 sprintf(nControl->response, "Invalid open type %d\n", typ); 882 sprintf(nControl->response, "Invalid open type %d\n", typ);
883 return 0; 883 return 0;
884 } 884 }
885 if (path != NULL) 885 if (path != NULL)
886 { 886 {
887 int i = strlen(buf); 887 int i = strlen(buf);
888 buf[i++] = ' '; 888 buf[i++] = ' ';
889 if ((strlen(path) + i) >= sizeof(buf)) 889 if ((strlen(path) + i) >= sizeof(buf))
890 return 0; 890 return 0;
891 strcpy(&buf[i],path); 891 strcpy(&buf[i],path);
892 } 892 }
893 if (FtpOpenPort(nControl, nData, mode, dir) == -1) 893 if (FtpOpenPort(nControl, nData, mode, dir) == -1)
894 return 0; 894 return 0;
895 if (!FtpSendCmd(buf, '1', nControl)) 895 if (!FtpSendCmd(buf, '1', nControl))
896 { 896 {
897 FtpClose(*nData); 897 FtpClose(*nData);
898 *nData = NULL; 898 *nData = NULL;
899 return 0; 899 return 0;
900 } 900 }
901 (*nData)->ctrl = nControl; 901 (*nData)->ctrl = nControl;
902 nControl->data = *nData; 902 nControl->data = *nData;
903 if (nControl->cmode == FTPLIB_PORT) 903 if (nControl->cmode == FTPLIB_PORT)
904 { 904 {
905 if (!FtpAcceptConnection(*nData,nControl)) 905 if (!FtpAcceptConnection(*nData,nControl))
906 { 906 {
907 FtpClose(*nData); 907 FtpClose(*nData);
908 *nData = NULL; 908 *nData = NULL;
909 nControl->data = NULL; 909 nControl->data = NULL;
910 return 0; 910 return 0;
911 } 911 }
912 } 912 }
913 return 1; 913 return 1;
914} 914}
915 915
916/* 916/*
917 * FtpRead - read from a data connection 917 * FtpRead - read from a data connection
918 */ 918 */
919GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) 919GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData)
920{ 920{
921 int i; 921 int i;
922 if (nData->dir != FTPLIB_READ) 922 if (nData->dir != FTPLIB_READ)
923 return 0; 923 return 0;
924 if (nData->buf) 924 if (nData->buf)
925 i = readline(buf, max, nData); 925 i = readline(buf, max, nData);
926 else 926 else
927 { 927 {
928 i = socket_wait(nData); 928 i = socket_wait(nData);
929 if (i != 1) 929 if (i != 1)
930 return 0; 930 return 0;
931 i = net_read(nData->handle, buf, max); 931 i = net_read(nData->handle, buf, max);
932 } 932 }
933 if (i == -1) 933 if (i == -1)
934 return 0; 934 return 0;
935 nData->xfered += i; 935 nData->xfered += i;
936 if (nData->idlecb && nData->cbbytes) 936 if (nData->idlecb && nData->cbbytes)
937 { 937 {
938 nData->xfered1 += i; 938 nData->xfered1 += i;
939 if (nData->xfered1 > nData->cbbytes) 939 if (nData->xfered1 > nData->cbbytes)
940 { 940 {
941 if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) 941 if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0)
942 return 0; 942 return 0;
943 nData->xfered1 = 0; 943 nData->xfered1 = 0;
944 } 944 }
945 } 945 }
946 return i; 946 return i;
947} 947}
948 948
949/* 949/*
950 * FtpWrite - write to a data connection 950 * FtpWrite - write to a data connection
951 */ 951 */
952GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) 952GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData)
953{ 953{
954 int i; 954 int i;
955 if (nData->dir != FTPLIB_WRITE) 955 if (nData->dir != FTPLIB_WRITE)
956 return 0; 956 return 0;
957 if (nData->buf) 957 if (nData->buf)
958 i = writeline(buf, len, nData); 958 i = writeline(buf, len, nData);
959 else 959 else
960 { 960 {
961 if (socket_wait(nData) < 0) 961 if (socket_wait(nData) < 0)
962 fprintf(stderr, "FtpWrite: socket_wait failed with %s\n", nData->ctrl->response); 962 fprintf(stderr, "FtpWrite: socket_wait failed with %s\n", nData->ctrl->response);
963 i = net_write(nData->handle, buf, len); 963 i = net_write(nData->handle, buf, len);
964 } 964 }
965 if (i == -1) 965 if (i == -1)
966 return 0; 966 return 0;
967 nData->xfered += i; 967 nData->xfered += i;
968 if (nData->idlecb && nData->cbbytes) 968 if (nData->idlecb && nData->cbbytes)
969 { 969 {
970 nData->xfered1 += i; 970 nData->xfered1 += i;
971 if (nData->xfered1 > nData->cbbytes) 971 if (nData->xfered1 > nData->cbbytes)
972 { 972 {
973 nData->idlecb(nData, nData->xfered, nData->idlearg); 973 nData->idlecb(nData, nData->xfered, nData->idlearg);
974 nData->xfered1 = 0; 974 nData->xfered1 = 0;
975 } 975 }
976 } 976 }
977 return i; 977 return i;
978} 978}
979 979
980/* 980/*
981 * FtpClose - close a data connection 981 * FtpClose - close a data connection
982 */ 982 */
983GLOBALDEF int FtpClose(netbuf *nData) 983GLOBALDEF int FtpClose(netbuf *nData)
984{ 984{
985 netbuf *ctrl; 985 netbuf *ctrl;
986 switch (nData->dir) 986 switch (nData->dir)
987 { 987 {
988 case FTPLIB_WRITE: 988 case FTPLIB_WRITE:
989 /* potential problem - if buffer flush fails, how to notify user? */ 989 /* potential problem - if buffer flush fails, how to notify user? */
990 if (nData->buf != NULL) 990 if (nData->buf != NULL)
991 writeline(NULL, 0, nData); 991 writeline(NULL, 0, nData);
992 case FTPLIB_READ: 992 case FTPLIB_READ:
993 if (nData->buf) 993 if (nData->buf)
994 free(nData->buf); 994 free(nData->buf);
995 shutdown(nData->handle,2); 995 shutdown(nData->handle,2);
996 net_close(nData->handle); 996 net_close(nData->handle);
997 ctrl = nData->ctrl; 997 ctrl = nData->ctrl;
998 free(nData); 998 free(nData);
999 if (ctrl) 999 if (ctrl)
1000 { 1000 {
1001 ctrl->data = NULL; 1001 ctrl->data = NULL;
1002 return(readresp('2', ctrl)); 1002 return(readresp('2', ctrl));
1003 } 1003 }
1004 return 1; 1004 return 1;
1005 case FTPLIB_CONTROL: 1005 case FTPLIB_CONTROL:
1006 if (nData->data) 1006 if (nData->data)
1007 { 1007 {
1008 nData->ctrl = NULL; 1008 nData->ctrl = NULL;
1009 FtpClose(nData); 1009 FtpClose(nData);
1010 } 1010 }
1011 net_close(nData->handle); 1011 net_close(nData->handle);
1012 free(nData); 1012 free(nData);
1013 return 0; 1013 return 0;
1014 } 1014 }
1015 return 1; 1015 return 1;
1016} 1016}
1017 1017
1018/* 1018/*
1019 * FtpSite - send a SITE command 1019 * FtpSite - send a SITE command
1020 * 1020 *
1021 * return 1 if command successful, 0 otherwise 1021 * return 1 if command successful, 0 otherwise
1022 */ 1022 */
1023GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) 1023GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl)
1024{ 1024{
1025 char buf[256]; 1025 char buf[256];
1026 1026
1027 if ((strlen(cmd) + 7) > sizeof(buf)) 1027 if ((strlen(cmd) + 7) > sizeof(buf))
1028 return 0; 1028 return 0;
1029 sprintf(buf,"SITE %s",cmd); 1029 sprintf(buf,"SITE %s",cmd);
1030 if (!FtpSendCmd(buf,'2',nControl)) 1030 if (!FtpSendCmd(buf,'2',nControl))
1031 return 0; 1031 return 0;
1032 return 1; 1032 return 1;
1033} 1033}
1034 1034
1035/* 1035/*
1036 * FtpSysType - send a SYST command 1036 * FtpSysType - send a SYST command
1037 * 1037 *
1038 * Fills in the user buffer with the remote system type. If more 1038 * Fills in the user buffer with the remote system type. If more
1039 * information from the response is required, the user can parse 1039 * information from the response is required, the user can parse
1040 * it out of the response buffer returned by FtpLastResponse(). 1040 * it out of the response buffer returned by FtpLastResponse().
1041 * 1041 *
1042 * return 1 if command successful, 0 otherwise 1042 * return 1 if command successful, 0 otherwise
1043 */ 1043 */
1044GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) 1044GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl)
1045{ 1045{
1046 int l = max; 1046 int l = max;
1047 char *b = buf; 1047 char *b = buf;
1048 char *s; 1048 char *s;
1049 if (!FtpSendCmd("SYST",'2',nControl)) 1049 if (!FtpSendCmd("SYST",'2',nControl))
1050 return 0; 1050 return 0;
1051 s = &nControl->response[4]; 1051 s = &nControl->response[4];
1052 while ((--l) && (*s != ' ')) 1052 while ((--l) && (*s != ' '))
1053 *b++ = *s++; 1053 *b++ = *s++;
1054 *b++ = '\0'; 1054 *b++ = '\0';
1055 return 1; 1055 return 1;
1056} 1056}
1057 1057
1058/* 1058/*
1059 * FtpMkdir - create a directory at server 1059 * FtpMkdir - create a directory at server
1060 * 1060 *
1061 * return 1 if successful, 0 otherwise 1061 * return 1 if successful, 0 otherwise
1062 */ 1062 */
1063GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) 1063GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl)
1064{ 1064{
1065 char buf[256]; 1065 char buf[256];
1066 1066
1067 if ((strlen(path) + 6) > sizeof(buf)) 1067 if ((strlen(path) + 6) > sizeof(buf))
1068 return 0; 1068 return 0;
1069 sprintf(buf,"MKD %s",path); 1069 sprintf(buf,"MKD %s",path);
1070 if (!FtpSendCmd(buf,'2', nControl)) 1070 if (!FtpSendCmd(buf,'2', nControl))
1071 return 0; 1071 return 0;
1072 return 1; 1072 return 1;
1073} 1073}
1074 1074
1075/* 1075/*
1076 * FtpChdir - change path at remote 1076 * FtpChdir - change path at remote
1077 * 1077 *
1078 * return 1 if successful, 0 otherwise 1078 * return 1 if successful, 0 otherwise
1079 */ 1079 */
1080GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) 1080GLOBALDEF int FtpChdir(const char *path, netbuf *nControl)
1081{ 1081{
1082 char buf[256]; 1082 char buf[256];
1083 1083
1084 if ((strlen(path) + 6) > sizeof(buf)) 1084 if ((strlen(path) + 6) > sizeof(buf))
1085 return 0; 1085 return 0;
1086 sprintf(buf,"CWD %s",path); 1086 sprintf(buf,"CWD %s",path);
1087 if (!FtpSendCmd(buf,'2',nControl)) 1087 if (!FtpSendCmd(buf,'2',nControl))
1088 return 0; 1088 return 0;
1089 return 1; 1089 return 1;
1090} 1090}
1091 1091
1092/* 1092/*
1093 * FtpCDUp - move to parent directory at remote 1093 * FtpCDUp - move to parent directory at remote
1094 * 1094 *
1095 * return 1 if successful, 0 otherwise 1095 * return 1 if successful, 0 otherwise
1096 */ 1096 */
1097GLOBALDEF int FtpCDUp(netbuf *nControl) 1097GLOBALDEF int FtpCDUp(netbuf *nControl)
1098{ 1098{
1099 if (!FtpSendCmd("CDUP",'2',nControl)) 1099 if (!FtpSendCmd("CDUP",'2',nControl))
1100 return 0; 1100 return 0;
1101 return 1; 1101 return 1;
1102} 1102}
1103 1103
1104/* 1104/*
1105 * FtpRmdir - remove directory at remote 1105 * FtpRmdir - remove directory at remote
1106 * 1106 *
1107 * return 1 if successful, 0 otherwise 1107 * return 1 if successful, 0 otherwise
1108 */ 1108 */
1109GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) 1109GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl)
1110{ 1110{
1111 char buf[256]; 1111 char buf[256];
1112 1112
1113 if ((strlen(path) + 6) > sizeof(buf)) 1113 if ((strlen(path) + 6) > sizeof(buf))
1114 return 0; 1114 return 0;
1115 sprintf(buf,"RMD %s",path); 1115 sprintf(buf,"RMD %s",path);
1116 if (!FtpSendCmd(buf,'2',nControl)) 1116 if (!FtpSendCmd(buf,'2',nControl))
1117 return 0; 1117 return 0;
1118 return 1; 1118 return 1;
1119} 1119}
1120 1120
1121/* 1121/*
1122 * FtpPwd - get working directory at remote 1122 * FtpPwd - get working directory at remote
1123 * 1123 *
1124 * return 1 if successful, 0 otherwise 1124 * return 1 if successful, 0 otherwise
1125 */ 1125 */
1126GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) 1126GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl)
1127{ 1127{
1128 int l = max; 1128 int l = max;
1129 char *b = path; 1129 char *b = path;
1130 char *s; 1130 char *s;
1131 if (!FtpSendCmd("PWD",'2',nControl)) 1131 if (!FtpSendCmd("PWD",'2',nControl))
1132 return 0; 1132 return 0;
1133 s = strchr(nControl->response, '"'); 1133 s = strchr(nControl->response, '"');
1134 if (s == NULL) 1134 if (s == NULL)
1135 return 0; 1135 return 0;
1136 s++; 1136 s++;
1137 while ((--l) && (*s) && (*s != '"')) 1137 while ((--l) && (*s) && (*s != '"'))
1138 *b++ = *s++; 1138 *b++ = *s++;
1139 *b++ = '\0'; 1139 *b++ = '\0';
1140 return 1; 1140 return 1;
1141} 1141}
1142 1142
1143/* 1143/*
1144 * FtpXfer - issue a command and transfer data 1144 * FtpXfer - issue a command and transfer data
1145 * 1145 *
1146 * return 1 if successful, 0 otherwise 1146 * return 1 if successful, 0 otherwise
1147 */ 1147 */
1148static int FtpXfer(const char *localfile, const char *path, 1148static int FtpXfer(const char *localfile, const char *path,
1149 netbuf *nControl, int typ, int mode) 1149 netbuf *nControl, int typ, int mode)
1150{ 1150{
1151 int l,c; 1151 int l,c;
1152 char *dbuf; 1152 char *dbuf;
1153 FILE *local = NULL; 1153 FILE *local = NULL;
1154 netbuf *nData; 1154 netbuf *nData;
1155 int rv=1; 1155 int rv=1;
1156 1156
1157 if (localfile != NULL) 1157 if (localfile != NULL)
1158 { 1158 {
1159 char ac[4] = "w"; 1159 char ac[4] = "w";
1160 if (typ == FTPLIB_FILE_WRITE) 1160 if (typ == FTPLIB_FILE_WRITE)
1161 ac[0] = 'r'; 1161 ac[0] = 'r';
1162 if (mode == FTPLIB_IMAGE) 1162 if (mode == FTPLIB_IMAGE)
1163 ac[1] = 'b'; 1163 ac[1] = 'b';
1164 local = fopen(localfile, ac); 1164 local = fopen(localfile, ac);
1165 if (local == NULL) 1165 if (local == NULL)
1166 { 1166 {
1167 strncpy(nControl->response, strerror(errno), 1167 strncpy(nControl->response, strerror(errno),
1168 sizeof(nControl->response)); 1168 sizeof(nControl->response));
1169 return 0; 1169 return 0;
1170 } 1170 }
1171 } 1171 }
1172 if (local == NULL) 1172 if (local == NULL)
1173 local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; 1173 local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout;
1174 if (!FtpAccess(path, typ, mode, nControl, &nData)) 1174 if (!FtpAccess(path, typ, mode, nControl, &nData))
1175 {
1176 if (localfile != NULL)
1177 fclose(local);
1175 return 0; 1178 return 0;
1179 }
1176 dbuf = malloc(FTPLIB_BUFSIZ); 1180 dbuf = malloc(FTPLIB_BUFSIZ);
1177 if (typ == FTPLIB_FILE_WRITE) 1181 if (typ == FTPLIB_FILE_WRITE)
1178 { 1182 {
1179 while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) 1183 while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0)
1180 if ((c = FtpWrite(dbuf, l, nData)) < l) 1184 if ((c = FtpWrite(dbuf, l, nData)) < l)
1181 { 1185 {
1182 printf("short write: passed %d, wrote %d\n", l, c); 1186 printf("short write: passed %d, wrote %d\n", l, c);
1183 rv = 0; 1187 rv = 0;
1184 break; 1188 break;
1185 } 1189 }
1186 } 1190 }
1187 else 1191 else
1188 { 1192 {
1189 while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) 1193 while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0)
1190 if (fwrite(dbuf, 1, l, local) <= 0) 1194 if (fwrite(dbuf, 1, l, local) <= 0)
1191 { 1195 {
1192 perror("localfile write"); 1196 perror("localfile write");
1193 rv = 0; 1197 rv = 0;
1194 break; 1198 break;
1195 } 1199 }
1196 } 1200 }
1197 free(dbuf); 1201 free(dbuf);
1198 fflush(local); 1202 fflush(local);
1199 if (localfile != NULL) 1203 if (localfile != NULL)
1200 fclose(local); 1204 fclose(local);
1201 FtpClose(nData); 1205 FtpClose(nData);
1202 return rv; 1206 return rv;
1203} 1207}
1204 1208
1205/* 1209/*
1206 * FtpNlst - issue an NLST command and write response to output 1210 * FtpNlst - issue an NLST command and write response to output
1207 * 1211 *
1208 * return 1 if successful, 0 otherwise 1212 * return 1 if successful, 0 otherwise
1209 */ 1213 */
1210GLOBALDEF int FtpNlst(const char *outputfile, const char *path, 1214GLOBALDEF int FtpNlst(const char *outputfile, const char *path,
1211 netbuf *nControl) 1215 netbuf *nControl)
1212{ 1216{
1213 return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII); 1217 return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII);
1214} 1218}
1215 1219
1216/* 1220/*
1217 * FtpDir - issue a LIST command and write response to output 1221 * FtpDir - issue a LIST command and write response to output
1218 * 1222 *
1219 * return 1 if successful, 0 otherwise 1223 * return 1 if successful, 0 otherwise
1220 */ 1224 */
1221GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) 1225GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl)
1222{ 1226{
1223 return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII); 1227 return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII);
1224} 1228}
1225 1229
1226/* 1230/*
1227 * FtpSize - determine the size of a remote file 1231 * FtpSize - determine the size of a remote file
1228 * 1232 *
1229 * return 1 if successful, 0 otherwise 1233 * return 1 if successful, 0 otherwise
1230 */ 1234 */
1231GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) 1235GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl)
1232{ 1236{
1233 char cmd[256]; 1237 char cmd[256];
1234 int resp,sz,rv=1; 1238 int resp,sz,rv=1;
1235 1239
1236 if ((strlen(path) + 7) > sizeof(cmd)) 1240 if ((strlen(path) + 7) > sizeof(cmd))
1237 return 0; 1241 return 0;
1238 sprintf(cmd, "TYPE %c", mode); 1242 sprintf(cmd, "TYPE %c", mode);
1239 if (!FtpSendCmd(cmd, '2', nControl)) 1243 if (!FtpSendCmd(cmd, '2', nControl))
1240 return 0; 1244 return 0;
1241 sprintf(cmd,"SIZE %s",path); 1245 sprintf(cmd,"SIZE %s",path);
1242 if (!FtpSendCmd(cmd,'2',nControl)) 1246 if (!FtpSendCmd(cmd,'2',nControl))
1243 rv = 0; 1247 rv = 0;
1244 else 1248 else
1245 { 1249 {
1246 if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) 1250 if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2)
1247 *size = sz; 1251 *size = sz;
1248 else 1252 else
1249 rv = 0; 1253 rv = 0;
1250 } 1254 }
1251 return rv; 1255 return rv;
1252} 1256}
1253 1257
1254/* 1258/*
1255 * FtpModDate - determine the modification date of a remote file 1259 * FtpModDate - determine the modification date of a remote file
1256 * 1260 *
1257 * return 1 if successful, 0 otherwise 1261 * return 1 if successful, 0 otherwise
1258 */ 1262 */
1259GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) 1263GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl)
1260{ 1264{
1261 char buf[256]; 1265 char buf[256];
1262 int rv = 1; 1266 int rv = 1;
1263 1267
1264 if ((strlen(path) + 7) > sizeof(buf)) 1268 if ((strlen(path) + 7) > sizeof(buf))
1265 return 0; 1269 return 0;
1266 sprintf(buf,"MDTM %s",path); 1270 sprintf(buf,"MDTM %s",path);
1267 if (!FtpSendCmd(buf,'2',nControl)) 1271 if (!FtpSendCmd(buf,'2',nControl))
1268 rv = 0; 1272 rv = 0;
1269 else 1273 else
1270 strncpy(dt, &nControl->response[4], max); 1274 strncpy(dt, &nControl->response[4], max);
1271 return rv; 1275 return rv;
1272} 1276}
1273 1277
1274/* 1278/*
1275 * FtpGet - issue a GET command and write received data to output 1279 * FtpGet - issue a GET command and write received data to output
1276 * 1280 *
1277 * return 1 if successful, 0 otherwise 1281 * return 1 if successful, 0 otherwise
1278 */ 1282 */
1279GLOBALDEF int FtpGet(const char *outputfile, const char *path, 1283GLOBALDEF int FtpGet(const char *outputfile, const char *path,
1280 char mode, netbuf *nControl) 1284 char mode, netbuf *nControl)
1281{ 1285{
1282 return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode); 1286 return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode);
1283} 1287}
1284 1288
1285/* 1289/*
1286 * FtpPut - issue a PUT command and send data from input 1290 * FtpPut - issue a PUT command and send data from input
1287 * 1291 *
1288 * return 1 if successful, 0 otherwise 1292 * return 1 if successful, 0 otherwise
1289 */ 1293 */
1290GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, 1294GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode,
1291 netbuf *nControl) 1295 netbuf *nControl)
1292{ 1296{
1293 return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode); 1297 return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode);
1294} 1298}
1295 1299
1296/* 1300/*
1297 * FtpRename - rename a file at remote 1301 * FtpRename - rename a file at remote
1298 * 1302 *
1299 * return 1 if successful, 0 otherwise 1303 * return 1 if successful, 0 otherwise
1300 */ 1304 */
1301GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) 1305GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl)
1302{ 1306{
1303 char cmd[256]; 1307 char cmd[256];
1304 1308
1305 if (((strlen(src) + 7) > sizeof(cmd)) || 1309 if (((strlen(src) + 7) > sizeof(cmd)) ||
1306 ((strlen(dst) + 7) > sizeof(cmd))) 1310 ((strlen(dst) + 7) > sizeof(cmd)))
1307 return 0; 1311 return 0;
1308 sprintf(cmd,"RNFR %s",src); 1312 sprintf(cmd,"RNFR %s",src);
1309 if (!FtpSendCmd(cmd,'3',nControl)) 1313 if (!FtpSendCmd(cmd,'3',nControl))
1310 return 0; 1314 return 0;
1311 sprintf(cmd,"RNTO %s",dst); 1315 sprintf(cmd,"RNTO %s",dst);
1312 if (!FtpSendCmd(cmd,'2',nControl)) 1316 if (!FtpSendCmd(cmd,'2',nControl))
1313 return 0; 1317 return 0;
1314 return 1; 1318 return 1;
1315} 1319}
1316 1320
1317/* 1321/*
1318 * FtpDelete - delete a file at remote 1322 * FtpDelete - delete a file at remote
1319 * 1323 *
1320 * return 1 if successful, 0 otherwise 1324 * return 1 if successful, 0 otherwise
1321 */ 1325 */
1322GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) 1326GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl)
1323{ 1327{
1324 char cmd[256]; 1328 char cmd[256];
1325 1329
1326 if ((strlen(fnm) + 7) > sizeof(cmd)) 1330 if ((strlen(fnm) + 7) > sizeof(cmd))
1327 return 0; 1331 return 0;
1328 sprintf(cmd,"DELE %s",fnm); 1332 sprintf(cmd,"DELE %s",fnm);
1329 if (!FtpSendCmd(cmd,'2', nControl)) 1333 if (!FtpSendCmd(cmd,'2', nControl))
1330 return 0; 1334 return 0;
1331 return 1; 1335 return 1;
1332} 1336}
1333 1337
1334/* 1338/*
1335 * FtpQuit - disconnect from remote 1339 * FtpQuit - disconnect from remote
1336 * 1340 *
1337 * return 1 if successful, 0 otherwise 1341 * return 1 if successful, 0 otherwise
1338 */ 1342 */
1339GLOBALDEF void FtpQuit(netbuf *nControl) 1343GLOBALDEF void FtpQuit(netbuf *nControl)
1340{ 1344{
1341 if (nControl->dir != FTPLIB_CONTROL) 1345 if (nControl->dir != FTPLIB_CONTROL)
1342 return; 1346 return;
1343 if (FtpSendCmd("QUIT",'2',nControl) == 1) { 1347 if (FtpSendCmd("QUIT",'2',nControl) == 1) {
1344 if (ftplib_debug > 2) 1348 if (ftplib_debug > 2)
1345 fprintf(stderr, "FtpQuit: FtpSendCmd(QUIT) failed\n"); 1349 fprintf(stderr, "FtpQuit: FtpSendCmd(QUIT) failed\n");
1346 } 1350 }
1347 net_close(nControl->handle); 1351 net_close(nControl->handle);
1348 free(nControl->buf); 1352 free(nControl->buf);
1349 free(nControl); 1353 free(nControl);
1350} 1354}
diff --git a/noncore/todayplugins/stockticker/libstocks/csv.c b/noncore/todayplugins/stockticker/libstocks/csv.c
index 86d8607..110df7c 100644
--- a/noncore/todayplugins/stockticker/libstocks/csv.c
+++ b/noncore/todayplugins/stockticker/libstocks/csv.c
@@ -1,406 +1,480 @@
1/* libstocks - Library to get current stock quotes from Yahoo Finance 1/* libstocks - Library to get current stock quotes from Yahoo Finance
2 * 2 *
3 * Copyright (C) 2000 Eric Laeuffer 3 * Copyright (C) 2000 Eric Laeuffer
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public 15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the 16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA. 18 * Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21#define __CSV_C__ 21#define __CSV_C__
22#ifndef __UNIX__ 22#ifndef __UNIX__
23#define __UNIX__ 23#define __UNIX__
24#endif 24#endif
25 25
26#include <string.h> 26#include <string.h>
27#include <stdlib.h> 27#include <stdlib.h>
28#include <stdio.h> 28#include <stdio.h>
29 29
30#ifdef __WINDOWS__ 30#ifdef __WINDOWS__
31#include <mbstring.h> 31#include <mbstring.h>
32#endif 32#endif
33 33
34#include "csv.h" 34#include "csv.h"
35#include "stocks.h" 35#include "stocks.h"
36#include "lists.h" 36#include "lists.h"
37 37
38#define DATE_LENGTH 7 /*YYMMDD*/ 38#define DATE_LENGTH 7 /*YYMMDD*/
39 39
40const char *months[12]= 40const char *months[12]=
41{ 41{
42 "Jan", 42 "Jan",
43 "Feb", 43 "Feb",
44 "Mar", 44 "Mar",
45 "Apr", 45 "Apr",
46 "May", 46 "May",
47 "Jun", 47 "Jun",
48 "Jul", 48 "Jul",
49 "Aug", 49 "Aug",
50 "Sep", 50 "Sep",
51 "Oct", 51 "Oct",
52 "Nov", 52 "Nov",
53 "Dec" 53 "Dec"
54}; 54};
55 55
56/*****************************************************************************/ 56/*****************************************************************************/
57/* Replacement of the strtok function. This one forgets "delim" when it is */ 57/* Replacement of the strtok function. This one forgets "delim" when it is */
58/* between two commas. */ 58/* between two commas. */
59/* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */ 59/* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */
60/*****************************************************************************/ 60/*****************************************************************************/
61char *csv_strtok(char *s, char *delim) 61char *csv_strtok(char *s, char *delim)
62{ 62{
63 static char *next=NULL; 63 static char *next=NULL;
64 char *temp, *first; 64 char *temp, *first;
65 int comma=0; 65 int comma=0;
66 66
67 if (s!=NULL) first=s; 67 if (s!=NULL) first=s;
68 else first=next; 68 else first=next;
69 69
70 temp=first; 70 temp=first;
71 if (*temp=='\0') return NULL; 71 if (*temp=='\0') return NULL;
72 72
73 while (*temp!='\0' && ((*temp!=*delim) || comma)) 73 while (*temp!='\0' && ((*temp!=*delim) || comma))
74 { 74 {
75 if (*temp=='"') comma ^= 1; 75 if (*temp=='"') comma ^= 1;
76 temp++; 76 temp++;
77 } 77 }
78 78
79 if (*temp=='\0') next=temp; 79 if (*temp=='\0') next=temp;
80 else 80 else
81 { 81 {
82 *temp='\0'; 82 *temp='\0';
83 next=temp+1; 83 next=temp+1;
84 } 84 }
85 85
86 return first; 86 return first;
87} 87}
88 88
89/*****************************************************************************/ 89/*****************************************************************************/
90/* Parses the csv file and return a list of stocks structure. */ 90/* Parses the csv file and return a list of stocks structure. */
91/* *csv points on the csv file in memory */ 91/* *csv points on the csv file in memory */
92/* count defines the country, because csv depends on the country */ 92/* count defines the country, because csv depends on the country */
93/*****************************************************************************/ 93/*****************************************************************************/
94stock *parse_csv_file(char *csv) 94stock *parse_csv_file(char *csv)
95{ 95{
96 char *line; 96 char *line;
97 char *end_line; 97 char *end_line;
98 98
99 char *ptr; 99 char *ptr;
100 100
101 char *date; 101 char *date;
102 char *time; 102 char *time;
103 char *name; 103 char *name;
104 char *symbol; 104 char *symbol;
105 105
106 stock *StockPtr=NULL; 106 stock *StockPtr=NULL;
107 stock *LastStockPtr=NULL; 107 stock *LastStockPtr=NULL;
108 108
109 /* Used to return the pointer to the list */ 109 /* Used to return the pointer to the list */
110 stock *FirstStockPtr=NULL; 110 stock *FirstStockPtr=NULL;
111 111
112 /* used to see if symbol is valid */ 112 /* used to see if symbol is valid */
113 int valid; 113 int valid;
114 char *test; 114 char *test;
115 115
116 line = csv; 116 line = csv;
117 end_line = csv; 117 end_line = csv;
118 118
119 while ((end_line = strstr(line, "\n"))) 119 while ((end_line = strstr(line, "\n")))
120 { 120 {
121 *end_line = 0; 121 *end_line = 0;
122 122
123 /* Check if symbol valid */ 123 /* Check if symbol valid */
124 /* if 1 "N/A" then ok because Indices have N/A for volume */ 124 /* if 1 "N/A" then ok because Indices have N/A for volume */
125 /* if 4 "N/A" then ok because Mutual funds have */ 125 /* if 4 "N/A" then ok because Mutual funds have */
126 /* if 5 "N/A" then ok because currencies have */ 126 /* if 5 "N/A" then ok because currencies have */
127 /* So if >5 then stock not valid */ 127 /* So if >5 then stock not valid */
128 128
129 test = line; 129 test = line;
130 valid = 0; 130 valid = 0;
131 while ( (test = strstr(test, "N/A")) ) 131 while ( (test = strstr(test, "N/A")) )
132 { 132 {
133 valid ++; 133 valid ++;
134 test = test +3; 134 test = test +3;
135 } 135 }
136 136
137 if (valid < 6) 137 if (valid < 6)
138 { 138 {
139 /* This Symbol is valid */ 139 /* This Symbol is valid */
140 140
141 StockPtr = malloc_stock(); 141 StockPtr = malloc_stock();
142 142
143 ptr = csv_strtok(line, ","); 143 ptr = csv_strtok(line, ",");
144 if (!ptr) return 0; 144 if (!ptr)
145 {
146 free_stock(StockPtr);
147 return 0;
148 }
145 149
146 symbol = (char *)malloc(strlen(ptr)+1); 150 symbol = (char *)malloc(strlen(ptr)+1);
147 if (symbol==NULL) 151 if (symbol==NULL)
148 { 152 {
149 fprintf(stderr,"Memory allocating error (%s line %d)\n" 153 fprintf(stderr,"Memory allocating error (%s line %d)\n"
150 ,__FILE__, __LINE__); 154 ,__FILE__, __LINE__);
151 exit(1); 155 exit(1);
152 } 156 }
153 strcpy((char *)(symbol), ptr); 157 strcpy((char *)(symbol), ptr);
154 StockPtr->Symbol = symbol; 158 StockPtr->Symbol = symbol;
155 159
156 ptr = csv_strtok(NULL, ","); 160 ptr = csv_strtok(NULL, ",");
157 if (!ptr) return 0; 161 if (!ptr)
162 {
163 free_stock(StockPtr);
164 return 0;
165 }
158 166
159 name = (char *)malloc(strlen(ptr)+1); 167 name = (char *)malloc(strlen(ptr)+1);
160 if (name==NULL) 168 if (name==NULL)
161 { 169 {
162 fprintf(stderr,"Memory allocating error (%s line %d)\n" 170 fprintf(stderr,"Memory allocating error (%s line %d)\n"
163 ,__FILE__, __LINE__); 171 ,__FILE__, __LINE__);
164 exit(1); 172 exit(1);
165 } 173 }
166 strcpy((char *)(name), ptr); 174 strcpy((char *)(name), ptr);
167 StockPtr->Name = name; 175 StockPtr->Name = name;
168 176
169 ptr = csv_strtok(NULL, ","); 177 ptr = csv_strtok(NULL, ",");
170 if (!ptr) return 0; 178 if (!ptr)
179 {
180 free_stock(StockPtr);
181 return 0;
182 }
171 sscanf(ptr,"%f",&(StockPtr->CurrentPrice)); 183 sscanf(ptr,"%f",&(StockPtr->CurrentPrice));
172 184
173 ptr = csv_strtok(NULL, ","); 185 ptr = csv_strtok(NULL, ",");
174 if (!ptr) return 0; 186 if (!ptr)
187 {
188 free_stock(StockPtr);
189 return 0;
190 }
175 191
176 date = (char *)malloc(strlen(ptr)+1); 192 date = (char *)malloc(strlen(ptr)+1);
177 if (date==NULL) 193 if (date==NULL)
178 { 194 {
179 fprintf(stderr,"Memory allocating error (%s line %d)\n" 195 fprintf(stderr,"Memory allocating error (%s line %d)\n"
180 ,__FILE__, __LINE__); 196 ,__FILE__, __LINE__);
181 exit(1); 197 exit(1);
182 } 198 }
183 strcpy((char *)(date), ptr); 199 strcpy((char *)(date), ptr);
184 StockPtr->Date = date; 200 StockPtr->Date = date;
185 201
186 ptr = csv_strtok(NULL, ","); 202 ptr = csv_strtok(NULL, ",");
187 if (!ptr) return 0; 203 if (!ptr)
204 {
205 free_stock(StockPtr);
206 return 0;
207 }
188 208
189 time = (char *)malloc(strlen(ptr)+1); 209 time = (char *)malloc(strlen(ptr)+1);
190 if (time==NULL) 210 if (time==NULL)
191 { 211 {
192 fprintf(stderr,"Memory allocating error (%s line %d)\n" 212 fprintf(stderr,"Memory allocating error (%s line %d)\n"
193 ,__FILE__, __LINE__); 213 ,__FILE__, __LINE__);
194 exit(1); 214 exit(1);
195 } 215 }
196 strcpy((char *)(time), ptr); 216 strcpy((char *)(time), ptr);
197 StockPtr->Time = time; 217 StockPtr->Time = time;
198 218
199 ptr = csv_strtok(NULL, ","); 219 ptr = csv_strtok(NULL, ",");
200 if (!ptr) return 0; 220 if (!ptr)
221 {
222 free_stock(StockPtr);
223 return 0;
224 }
201 sscanf(ptr,"%f",&(StockPtr->Variation)); 225 sscanf(ptr,"%f",&(StockPtr->Variation));
202 226
203 StockPtr->Pourcentage = 100 * StockPtr->Variation / 227 StockPtr->Pourcentage = 100 * StockPtr->Variation /
204 (StockPtr->CurrentPrice - StockPtr->Variation); 228 (StockPtr->CurrentPrice - StockPtr->Variation);
205 229
206 StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation; 230 StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation;
207 231
208 ptr = csv_strtok(NULL, ","); 232 ptr = csv_strtok(NULL, ",");
209 if (!ptr) return 0; 233 if (!ptr)
234 {
235 free_stock(StockPtr);
236 return 0;
237 }
210 sscanf(ptr,"%f",&(StockPtr->OpenPrice)); 238 sscanf(ptr,"%f",&(StockPtr->OpenPrice));
211 239
212 ptr = csv_strtok(NULL, ","); 240 ptr = csv_strtok(NULL, ",");
213 if (!ptr) return 0; 241 if (!ptr)
242 {
243 free_stock(StockPtr);
244 return 0;
245 }
214 sscanf(ptr,"%f",&(StockPtr->MaxPrice)); 246 sscanf(ptr,"%f",&(StockPtr->MaxPrice));
215 247
216 ptr = csv_strtok(NULL, ","); 248 ptr = csv_strtok(NULL, ",");
217 if (!ptr) return 0; 249 if (!ptr)
250 {
251 free_stock(StockPtr);
252 return 0;
253 }
218 sscanf(ptr,"%f",&(StockPtr->MinPrice)); 254 sscanf(ptr,"%f",&(StockPtr->MinPrice));
219 255
220 ptr = csv_strtok(NULL, ","); 256 ptr = csv_strtok(NULL, ",");
221 if (!ptr) return 0; 257 if (!ptr)
258 {
259 free_stock(StockPtr);
260 return 0;
261 }
222 StockPtr->Volume = atoi(ptr); 262 StockPtr->Volume = atoi(ptr);
223 263
224 if( !FirstStockPtr ) 264 if( !FirstStockPtr )
225 { 265 {
226 FirstStockPtr = StockPtr; 266 FirstStockPtr = StockPtr;
227 StockPtr->PreviousStock = 0; 267 StockPtr->PreviousStock = 0;
228 } 268 }
229 269
230 StockPtr->NextStock = 0; 270 StockPtr->NextStock = 0;
231 271
232 if (LastStockPtr) 272 if (LastStockPtr)
233 { 273 {
234 LastStockPtr->NextStock = StockPtr; 274 LastStockPtr->NextStock = StockPtr;
235 StockPtr->PreviousStock = LastStockPtr; 275 StockPtr->PreviousStock = LastStockPtr;
236 } 276 }
237 277
238 LastStockPtr = StockPtr; 278 LastStockPtr = StockPtr;
239 279
240 } 280 }
241 else 281 else
242 { 282 {
243 /* this symbol is not valid */ 283 /* this symbol is not valid */
244 /* Set the stock struct just with Symbol, all other are NULL */ 284 /* Set the stock struct just with Symbol, all other are NULL */
245 /* This can be used to see if the symbol has been reached are not */ 285 /* This can be used to see if the symbol has been reached are not */
246 286
247 StockPtr = malloc_stock(); 287 StockPtr = malloc_stock();
248 288
249 ptr = csv_strtok(line, ","); 289 ptr = csv_strtok(line, ",");
250 if (!ptr) return 0; 290 if (!ptr)
291 {
292 free_stock(StockPtr);
293 return 0;
294 }
251 295
252 symbol = (char *)malloc(strlen(ptr)+1); 296 symbol = (char *)malloc(strlen(ptr)+1);
253 if (symbol==NULL) 297 if (symbol==NULL)
254 { 298 {
255 fprintf(stderr,"Memory allocating error (%s line %d)\n" 299 fprintf(stderr,"Memory allocating error (%s line %d)\n"
256 ,__FILE__, __LINE__); 300 ,__FILE__, __LINE__);
257 exit(1); 301 exit(1);
258 } 302 }
259 strcpy((char *)(symbol), ptr); 303 strcpy((char *)(symbol), ptr);
260 StockPtr->Symbol = symbol; 304 StockPtr->Symbol = symbol;
261 305
262 if( !FirstStockPtr ) 306 if( !FirstStockPtr )
263 { 307 {
264 FirstStockPtr = StockPtr; 308 FirstStockPtr = StockPtr;
265 StockPtr->PreviousStock = 0; 309 StockPtr->PreviousStock = 0;
266 } 310 }
267 311
268 StockPtr->NextStock = 0; 312 StockPtr->NextStock = 0;
269 313
270 if (LastStockPtr) 314 if (LastStockPtr)
271 { 315 {
272 LastStockPtr->NextStock = StockPtr; 316 LastStockPtr->NextStock = StockPtr;
273 StockPtr->PreviousStock = LastStockPtr; 317 StockPtr->PreviousStock = LastStockPtr;
274 } 318 }
275 319
276 LastStockPtr = StockPtr; 320 LastStockPtr = StockPtr;
277 } 321 }
278 322
279 end_line++; 323 end_line++;
280 line = end_line; 324 line = end_line;
281 325
282 } 326 }
283 327
284 return (FirstStockPtr); 328 return (FirstStockPtr);
285} 329}
286 330
287/*****************************************************************************/ 331/*****************************************************************************/
288/* Parses the history quotes file and return a stock structure list. */ 332/* Parses the history quotes file and return a stock structure list. */
289/*****************************************************************************/ 333/*****************************************************************************/
290stock *parse_csv_history_file(char *csv_file) 334stock *parse_csv_history_file(char *csv_file)
291{ 335{
292 336
293 char *line; 337 char *line;
294 char *end_line; 338 char *end_line;
295 char *ptr; 339 char *ptr;
296 340
297 int day; 341 int day;
298 char smonth[10]; 342 char smonth[10];
299 int month; 343 int month;
300 int year; 344 int year;
301 345
302 char *date; 346 char *date;
303 347
304 int i; 348 int i;
305 int test; 349 int test;
306 350
307 stock *StockPtr=NULL; 351 stock *StockPtr=NULL;
308 stock *LastStockPtr=NULL; 352 stock *LastStockPtr=NULL;
309 353
310 /* Used to return the pointer to the list */ 354 /* Used to return the pointer to the list */
311 stock *FirstStockPtr=NULL; 355 stock *FirstStockPtr=NULL;
312 356
313 line = csv_file; 357 line = csv_file;
314 end_line = csv_file; 358 end_line = csv_file;
315 359
316 /* do not use the first line */ 360 /* do not use the first line */
317 if (!(end_line = strstr(line, "\n"))) 361 if (!(end_line = strstr(line, "\n")))
318 return 0; 362 return 0;
319 *end_line = 0; 363 *end_line = 0;
320 end_line++; 364 end_line++;
321 line = end_line; 365 line = end_line;
322 366
323 while ((end_line = strstr(line, "\n"))) 367 while ((end_line = strstr(line, "\n")))
324 { 368 {
325 *end_line = 0; 369 *end_line = 0;
326 370
327 StockPtr = malloc_stock(); 371 StockPtr = malloc_stock();
328 372
329 /* Date */ 373 /* Date */
330 ptr = strtok(line, ","); 374 ptr = strtok(line, ",");
331 if (!ptr) return 0; 375 if (!ptr)
376 {
377 free_stock(StockPtr);
378 free_stock(FirstStockPtr);
379 free_stock(LastStockPtr);
380 return 0;
381 }
332 382
333 sscanf(ptr,"%d-%3s-%d",&day,smonth,&year); 383 sscanf(ptr,"%d-%3s-%d",&day,smonth,&year);
334 384
335 i=0; 385 i=0;
336 386
337#ifdef __UNIX__ 387#ifdef __UNIX__
338 while((test=strcasecmp(months[i], smonth))) i++; 388 while((test=strcasecmp(months[i], smonth))) i++;
339#elif __WINDOWS__ 389#elif __WINDOWS__
340 while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++; 390 while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++;
341#endif 391#endif
342 392
343 month = i+1; 393 month = i+1;
344 394
345 date = (char *)malloc(DATE_LENGTH); 395 date = (char *)malloc(DATE_LENGTH);
346 if (date==NULL) 396 if (date==NULL)
347 { 397 {
348 fprintf(stderr,"Memory allocating error (%s line %d)\n" 398 fprintf(stderr,"Memory allocating error (%s line %d)\n"
349 ,__FILE__, __LINE__); 399 ,__FILE__, __LINE__);
350 exit(1); 400 exit(1);
351 } 401 }
352 sprintf(date,"%.2d%.2d%.2d", year, month, day); 402 sprintf(date,"%.2d%.2d%.2d", year, month, day);
353 StockPtr->Date = date; 403 StockPtr->Date = date;
354 404
355 /* Open */ 405 /* Open */
356 ptr = strtok(NULL, ","); 406 ptr = strtok(NULL, ",");
357 if (!ptr) return 0; 407 if (!ptr)
408 {
409 free_stock(StockPtr);
410 free_stock(FirstStockPtr);
411 free_stock(LastStockPtr);
412 return 0;
413 }
358 sscanf(ptr,"%f",&(StockPtr->OpenPrice)); 414 sscanf(ptr,"%f",&(StockPtr->OpenPrice));
359 415
360 /* High */ 416 /* High */
361 ptr = strtok(NULL, ","); 417 ptr = strtok(NULL, ",");
362 if (!ptr) return 0; 418 if (!ptr)
419 {
420 free_stock(StockPtr);
421 free_stock(FirstStockPtr);
422 free_stock(LastStockPtr);
423 return 0;
424 }
363 sscanf(ptr,"%f",&(StockPtr->MaxPrice)); 425 sscanf(ptr,"%f",&(StockPtr->MaxPrice));
364 426
365 /* Low */ 427 /* Low */
366 ptr = strtok(NULL, ","); 428 ptr = strtok(NULL, ",");
367 if (!ptr) return 0; 429 if (!ptr)
430 {
431 free_stock(StockPtr);
432 free_stock(FirstStockPtr);
433 free_stock(LastStockPtr);
434 return 0;
435 }
368 sscanf(ptr,"%f",&(StockPtr->MinPrice)); 436 sscanf(ptr,"%f",&(StockPtr->MinPrice));
369 437
370 /* Close */ 438 /* Close */
371 ptr = strtok(NULL, ","); 439 ptr = strtok(NULL, ",");
372 if (!ptr) return 0; 440 if (!ptr)
441 {
442 free_stock(StockPtr);
443 free_stock(FirstStockPtr);
444 free_stock(LastStockPtr);
445 return 0;
446 }
373 sscanf(ptr,"%f",&(StockPtr->LastPrice)); 447 sscanf(ptr,"%f",&(StockPtr->LastPrice));
374 448
375 /* Volume */ 449 /* Volume */
376 450
377 ptr = strtok(NULL, ","); 451 ptr = strtok(NULL, ",");
378 if (!ptr) 452 if (!ptr)
379 /* It seems to be an indice */ 453 /* It seems to be an indice */
380 /* No volume for indices */ 454 /* No volume for indices */
381 StockPtr->Volume = 0; 455 StockPtr->Volume = 0;
382 else 456 else
383 StockPtr->Volume = atoi(ptr); 457 StockPtr->Volume = atoi(ptr);
384 458
385 if( !FirstStockPtr ) 459 if( !FirstStockPtr )
386 { 460 {
387 FirstStockPtr = StockPtr; 461 FirstStockPtr = StockPtr;
388 StockPtr->PreviousStock = 0; 462 StockPtr->PreviousStock = 0;
389 } 463 }
390 464
391 StockPtr->NextStock = 0; 465 StockPtr->NextStock = 0;
392 466
393 if (LastStockPtr) 467 if (LastStockPtr)
394 { 468 {
395 LastStockPtr->NextStock = StockPtr; 469 LastStockPtr->NextStock = StockPtr;
396 StockPtr->PreviousStock = LastStockPtr; 470 StockPtr->PreviousStock = LastStockPtr;
397 } 471 }
398 472
399 LastStockPtr = StockPtr; 473 LastStockPtr = StockPtr;
400 474
401 end_line++; 475 end_line++;
402 line = end_line; 476 line = end_line;
403 } 477 }
404 478
405 return (FirstStockPtr); 479 return (FirstStockPtr);
406} 480}
diff --git a/noncore/todayplugins/stockticker/libstocks/currency.c b/noncore/todayplugins/stockticker/libstocks/currency.c
index 9a08a9d..e0090e2 100644
--- a/noncore/todayplugins/stockticker/libstocks/currency.c
+++ b/noncore/todayplugins/stockticker/libstocks/currency.c
@@ -1,66 +1,67 @@
1/* libstocks - Library to get current stock quotes from Yahoo Finance 1/* libstocks - Library to get current stock quotes from Yahoo Finance
2 * 2 *
3 * Copyright (C) 2000 Eric Laeuffer 3 * Copyright (C) 2000 Eric Laeuffer
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public 15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the 16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA. 18 * Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21#define __CURRENCY_C__ 21#define __CURRENCY_C__
22 22
23 23
24#include <stdio.h> 24#include <stdio.h>
25#include <string.h> 25#include <string.h>
26#include <malloc.h> 26#include <malloc.h>
27#include <stdlib.h> 27#include <stdlib.h>
28 28
29#include "stocks.h" 29#include "stocks.h"
30 30
31/*****************************************************************************/ 31/*****************************************************************************/
32/* returns the currency exchange rate of "from" currency into */ 32/* returns the currency exchange rate of "from" currency into */
33/* "into" currency. */ 33/* "into" currency. */
34/*****************************************************************************/ 34/*****************************************************************************/
35libstocks_return_code get_currency_exchange(char *from, 35libstocks_return_code get_currency_exchange(char *from,
36 char *into, 36 char *into,
37 float *exchange) 37 float *exchange)
38{ 38{
39 char *symbol; 39 char *symbol;
40 stock *data; 40 stock *data;
41 libstocks_return_code error; 41 libstocks_return_code error;
42 42
43 if((symbol = (char *)malloc(strlen(from)+strlen(into)+3))==NULL) 43 if((symbol = (char *)malloc(strlen(from)+strlen(into)+3))==NULL)
44 { 44 {
45 fprintf(stderr,"Memory allocating error (%s line %d)\n" 45 fprintf(stderr,"Memory allocating error (%s line %d)\n"
46 ,__FILE__, __LINE__); 46 ,__FILE__, __LINE__);
47 exit(1); 47 exit(1);
48 } 48 }
49 49
50 strcpy(symbol, from); 50 strcpy(symbol, from);
51 strcat(symbol, into); 51 strcat(symbol, into);
52 strcat(symbol, "=X"); 52 strcat(symbol, "=X");
53 53
54 error = get_stocks(symbol, &data); 54 error = get_stocks(symbol, &data);
55 free(symbol);
55 if (error) 56 if (error)
56 { 57 {
57 *exchange = 0; 58 *exchange = 0;
58 return(error); 59 return(error);
59 } 60 }
60 61
61 free_stocks(data); 62 free_stocks(data);
62 63
63 *exchange = data->CurrentPrice; 64 *exchange = data->CurrentPrice;
64 return(error); 65 return(error);
65 66
66} 67}
diff --git a/noncore/todayplugins/stockticker/libstocks/lists.h b/noncore/todayplugins/stockticker/libstocks/lists.h
index 0132317..a0eb434 100644
--- a/noncore/todayplugins/stockticker/libstocks/lists.h
+++ b/noncore/todayplugins/stockticker/libstocks/lists.h
@@ -1,35 +1,36 @@
1/* libstocks - Library to get current stock quotes from Yahoo Finance 1/* libstocks - Library to get current stock quotes from Yahoo Finance
2 * 2 *
3 * Copyright (C) 2000 Eric Laeuffer 3 * Copyright (C) 2000 Eric Laeuffer
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public 15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the 16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA. 18 * Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21#ifndef __LISTS_H__ 21#ifndef __LISTS_H__
22#define __LISTS_H__ 22#define __LISTS_H__
23 23
24#ifndef __LISTS_C__ 24#ifndef __LISTS_C__
25#define PUBEXT_LISTS extern 25#define PUBEXT_LISTS extern
26#else 26#else
27#define PUBEXT_LISTS 27#define PUBEXT_LISTS
28#endif 28#endif
29 29
30#include "stocks.h" 30#include "stocks.h"
31 31
32PUBEXT_LISTS stock *malloc_stock(void); 32PUBEXT_LISTS stock *malloc_stock(void);
33PUBEXT_LISTS void free_stock(stock*);
33 34
34 35
35#endif /* __LISTS_H */ 36#endif /* __LISTS_H */
diff --git a/noncore/todayplugins/stockticker/libstocks/stocks.c b/noncore/todayplugins/stockticker/libstocks/stocks.c
index eb04ba9..3a26a47 100644
--- a/noncore/todayplugins/stockticker/libstocks/stocks.c
+++ b/noncore/todayplugins/stockticker/libstocks/stocks.c
@@ -1,347 +1,348 @@
1/* libstocks - Library to get current stock quotes from Yahoo Finance 1/* libstocks - Library to get current stock quotes from Yahoo Finance
2 * 2 *
3 * Copyright (C) 2000 Eric Laeuffer 3 * Copyright (C) 2000 Eric Laeuffer
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public 15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the 16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA. 18 * Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21#define __STOCKS_C__ 21#define __STOCKS_C__
22 22
23#include <stdio.h> 23#include <stdio.h>
24#include <string.h> 24#include <string.h>
25#include <malloc.h> 25#include <malloc.h>
26#include <stdlib.h> 26#include <stdlib.h>
27 27
28#ifdef __WINDOWS__ 28#ifdef __WINDOWS__
29#include <mbstring.h> 29#include <mbstring.h>
30#endif 30#endif
31 31
32#include "http.h" 32#include "http.h"
33#include "csv.h" 33#include "csv.h"
34 34
35#include "stocks.h" 35#include "stocks.h"
36 36
37/* 37/*
38s = symbol 38s = symbol
39n = name 39n = name
40l1 = last trade 40l1 = last trade
41d1 = date 41d1 = date
42t1 = time 42t1 = time
43c1 = variation 43c1 = variation
44o = open 44o = open
45h = higher price 45h = higher price
46g = lower price 46g = lower price
47v = volume 47v = volume
48*/ 48*/
49 49
50const char yahoo_us_stocks_server[]="finance.yahoo.com"; 50const char yahoo_us_stocks_server[]="finance.yahoo.com";
51const char yahoo_eu_stocks_server[]="finance.yahoo.com"; 51const char yahoo_eu_stocks_server[]="finance.yahoo.com";
52//const char yahoo_eu_stocks_server[]="fr.finance.yahoo.com"; 52//const char yahoo_eu_stocks_server[]="fr.finance.yahoo.com";
53 53
54const char yahoo_url_beg[]="/d/quotes.csv?s="; 54const char yahoo_url_beg[]="/d/quotes.csv?s=";
55const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; 55const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv";
56 56
57typedef enum { 57typedef enum {
58 YAHOO_EUROPE, 58 YAHOO_EUROPE,
59 YAHOO_US 59 YAHOO_US
60} yahoo_source; 60} yahoo_source;
61 61
62#define YAHOO_US_EXT_NB 11 62#define YAHOO_US_EXT_NB 11
63const char *yahoo_us_ext[YAHOO_US_EXT_NB] = 63const char *yahoo_us_ext[YAHOO_US_EXT_NB] =
64{ 64{
65 ".US", /* United States */ 65 ".US", /* United States */
66 ".TO", /* Canada */ 66 ".TO", /* Canada */
67 ".M", /* Canada */ 67 ".M", /* Canada */
68 ".V", /* Canada */ 68 ".V", /* Canada */
69 ".AL", /* Canada */ 69 ".AL", /* Canada */
70 ".MX", /* Mexico */ 70 ".MX", /* Mexico */
71 ".SA", /* Brasil */ 71 ".SA", /* Brasil */
72 ".BA", /* Argentina */ 72 ".BA", /* Argentina */
73 ".CR", /* Venezuela */ 73 ".CR", /* Venezuela */
74 ".SN", /* Chili */ 74 ".SN", /* Chili */
75 ".AX" /* Australia */ 75 ".AX" /* Australia */
76}; 76};
77 77
78/*****************************************************************************/ 78/*****************************************************************************/
79/* Finds, according to the symbol extension, the http source of the quotes. */ 79/* Finds, according to the symbol extension, the http source of the quotes. */
80/* Actually just finance.yahoo.com and fr.finance.yahoo.com are supported. */ 80/* Actually just finance.yahoo.com and fr.finance.yahoo.com are supported. */
81/* The function returns the country source (US or EUROPE). */ 81/* The function returns the country source (US or EUROPE). */
82/*****************************************************************************/ 82/*****************************************************************************/
83yahoo_source find_yahoo_source(char *symbol) 83yahoo_source find_yahoo_source(char *symbol)
84{ 84{
85 char *ptr; 85 char *ptr;
86 int i; 86 int i;
87 int test; 87 int test;
88 88
89 ptr = strrchr(symbol, '.'); 89 ptr = strrchr(symbol, '.');
90 90
91 /* If no extension we suppose it is a US stock */ 91 /* If no extension we suppose it is a US stock */
92 if (!ptr) return YAHOO_US; 92 if (!ptr) return YAHOO_US;
93 93
94 /* extension is found */ 94 /* extension is found */
95 95
96 /* Test if it is canadian stock */ 96 /* Test if it is canadian stock */
97 for (i=0; i<YAHOO_US_EXT_NB; i++) 97 for (i=0; i<YAHOO_US_EXT_NB; i++)
98 { 98 {
99 99
100#ifdef __UNIX__ 100#ifdef __UNIX__
101 test = strcasecmp(yahoo_us_ext[i], ptr); 101 test = strcasecmp(yahoo_us_ext[i], ptr);
102#elif __WINDOWS__ 102#elif __WINDOWS__
103 test = _mbsnbicmp(yahoo_us_ext[i], ptr, strlen(yahoo_us_ext[i])); 103 test = _mbsnbicmp(yahoo_us_ext[i], ptr, strlen(yahoo_us_ext[i]));
104#endif 104#endif
105 105
106 if (!test) return YAHOO_US; 106 if (!test) return YAHOO_US;
107 } 107 }
108 108
109 /* We suppose now it is a European stock */ 109 /* We suppose now it is a European stock */
110 return YAHOO_EUROPE; 110 return YAHOO_EUROPE;
111} 111}
112 112
113/*****************************************************************************/ 113/*****************************************************************************/
114/* Gets quotes csv file, parses the file and create the quotes list */ 114/* Gets quotes csv file, parses the file and create the quotes list */
115/* *stocks points to the stocks to fetch */ 115/* *stocks points to the stocks to fetch */
116/* *stock_datas points to the beginning of the list */ 116/* *stock_datas points to the beginning of the list */
117/* count allows to connect to all country servers */ 117/* count allows to connect to all country servers */
118/*****************************************************************************/ 118/*****************************************************************************/
119libstocks_return_code download_stocks(char *stocks, 119libstocks_return_code download_stocks(char *stocks,
120 stock **stock_datas, 120 stock **stock_datas,
121 yahoo_source source) 121 yahoo_source source)
122{ 122{
123 char *stocks_server=NULL; 123 char *stocks_server=NULL;
124 char *url_beg=NULL; 124 char *url_beg=NULL;
125 char *url_end=NULL; 125 char *url_end=NULL;
126 126
127 char *url; 127 char *url;
128 char *data; 128 char *data;
129 129
130 libstocks_return_code error; 130 libstocks_return_code error;
131 131
132#ifdef DEBUG 132#ifdef DEBUG
133 printf("*download_stocks\n"); 133 printf("*download_stocks\n");
134#endif 134#endif
135 135
136 switch (source) 136 switch (source)
137 { 137 {
138 case YAHOO_US: 138 case YAHOO_US:
139 stocks_server = (char *)yahoo_us_stocks_server; 139 stocks_server = (char *)yahoo_us_stocks_server;
140 break; 140 break;
141 141
142 case YAHOO_EUROPE: 142 case YAHOO_EUROPE:
143 stocks_server = (char *)yahoo_eu_stocks_server; 143 stocks_server = (char *)yahoo_eu_stocks_server;
144 break; 144 break;
145 default: 145 default:
146 stocks_server = (char *)yahoo_us_stocks_server; 146 stocks_server = (char *)yahoo_us_stocks_server;
147 break; 147 break;
148 148
149 } 149 }
150 150
151 url_beg = (char *)yahoo_url_beg; 151 url_beg = (char *)yahoo_url_beg;
152 url_end = (char *)yahoo_url_end; 152 url_end = (char *)yahoo_url_end;
153 153
154 url = (char *)malloc(strlen(url_beg) 154 url = (char *)malloc(strlen(url_beg)
155 +strlen(url_end) 155 +strlen(url_end)
156 +strlen(stocks)+1); 156 +strlen(stocks)+1);
157 if (url==NULL) 157 if (url==NULL)
158 { 158 {
159 fprintf(stderr,"Memory allocating error (%s line %d)\n" 159 fprintf(stderr,"Memory allocating error (%s line %d)\n"
160 ,__FILE__, __LINE__); 160 ,__FILE__, __LINE__);
161 exit(1); 161 exit(1);
162 } 162 }
163 163
164 strcpy(url, url_beg); 164 strcpy(url, url_beg);
165 strcat(url, stocks); 165 strcat(url, stocks);
166 strcat(url, url_end); 166 strcat(url, url_end);
167 167
168 error=http_get(url, stocks_server, &data); 168 error=http_get(url, stocks_server, &data);
169 169
170 free(url); 170 free(url);
171 171
172 if (error) return error; 172 if (error) return error;
173 173
174 *stock_datas = parse_csv_file(data); 174 *stock_datas = parse_csv_file(data);
175 175
176 free(data); 176 free(data);
177 177
178 if (!(*stock_datas)) return ERRPCSV; 178 if (!(*stock_datas)) return ERRPCSV;
179 179
180 return 0; 180 return 0;
181 181
182} 182}
183 183
184/*****************************************************************************/ 184/*****************************************************************************/
185/* Gets quotes from yahoo */ 185/* Gets quotes from yahoo */
186/* Choses to fetch European or US depending on the symbol extension */ 186/* Choses to fetch European or US depending on the symbol extension */
187/* and merges the two lists to one */ 187/* and merges the two lists to one */
188/* *stocks points to the stocks to fetch */ 188/* *stocks points to the stocks to fetch */
189/* *stock_datas points to the beginning of the list */ 189/* *stock_datas points to the beginning of the list */
190/*****************************************************************************/ 190/*****************************************************************************/
191libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) 191libstocks_return_code get_stocks(const char *stocks, stock **stock_datas)
192{ 192{
193 char *tok_ptr; 193 char *tok_ptr;
194 char *eu_quotes=NULL; 194 char *eu_quotes=NULL;
195 char *eu_quotes_temp=NULL; 195 char *eu_quotes_temp=NULL;
196 int lgr_eu_quotes=0; 196 int lgr_eu_quotes=0;
197 197
198 char *us_quotes=NULL; 198 char *us_quotes=NULL;
199 char *us_quotes_temp=NULL; 199 char *us_quotes_temp=NULL;
200 int lgr_us_quotes=0; 200 int lgr_us_quotes=0;
201 201
202 char *symbol; 202 char *symbol;
203 203
204 yahoo_source source; 204 yahoo_source source;
205 205
206 int lgr_symbol=0; 206 int lgr_symbol=0;
207 207
208 libstocks_return_code error; 208 libstocks_return_code error;
209 209
210 stock *stocks_tmp=NULL; 210 stock *stocks_tmp=NULL;
211 stock *stocks_tmp2=NULL; 211 stock *stocks_tmp2=NULL;
212 stock *stocks_getted=NULL; 212 stock *stocks_getted=NULL;
213 stock *last_stock=NULL; 213 stock *last_stock=NULL;
214 214
215#ifdef DEBUG 215#ifdef DEBUG
216 printf("*get_stocks\n"); 216 printf("*get_stocks\n");
217#endif 217#endif
218 218
219 /* to preserve stocks */ 219 /* to preserve stocks */
220 tok_ptr = malloc(strlen(stocks)+1); 220 tok_ptr = malloc(strlen(stocks)+1);
221 if(tok_ptr==NULL) 221 if(tok_ptr==NULL)
222 { 222 {
223 fprintf(stderr,"Memory allocating error (%s line %d)\n" 223 fprintf(stderr,"Memory allocating error (%s line %d)\n"
224 ,__FILE__, __LINE__); 224 ,__FILE__, __LINE__);
225 exit(1); 225 exit(1);
226 } 226 }
227 strcpy(tok_ptr, stocks); 227 strcpy(tok_ptr, stocks);
228 228
229 while( (symbol = strtok(tok_ptr, "+"))!=0) 229 while( (symbol = strtok(tok_ptr, "+"))!=0)
230 { 230 {
231 /* clear tok_ptr for next strtok */ 231 /* clear tok_ptr for next strtok */
232 tok_ptr = NULL; 232 tok_ptr = NULL;
233 233
234 /* look for "." in the symbol */ 234 /* look for "." in the symbol */
235 source = find_yahoo_source(symbol); 235 source = find_yahoo_source(symbol);
236 236
237 switch (source) 237 switch (source)
238 { 238 {
239 case YAHOO_US: 239 case YAHOO_US:
240 240 if (us_quotes)
241 if (us_quotes) 241 {
242 { 242 lgr_us_quotes = strlen(us_quotes);
243 lgr_us_quotes = strlen(us_quotes); 243 lgr_symbol = strlen(symbol);
244 lgr_symbol = strlen(symbol); 244
245 245 us_quotes_temp = malloc(lgr_us_quotes + lgr_symbol +2);
246 us_quotes_temp = malloc(lgr_us_quotes + lgr_symbol +2); 246 if(us_quotes_temp==NULL)
247 if(us_quotes_temp==NULL) 247 {
248 { 248 fprintf(stderr,"Memory allocating error (%s line %d)\n",
249 fprintf(stderr,"Memory allocating error (%s line %d)\n" 249 __FILE__, __LINE__);
250 ,__FILE__, __LINE__); 250 exit(1);
251 exit(1); 251 }
252 } 252 strcpy(us_quotes_temp, us_quotes);
253 strcpy(us_quotes_temp, us_quotes); 253 strcat(us_quotes_temp,"+");
254 strcat(us_quotes_temp,"+"); 254 strcat(us_quotes_temp,symbol);
255 strcat(us_quotes_temp,symbol); 255
256 256 free(us_quotes);
257 free(us_quotes); 257 us_quotes = us_quotes_temp;
258 us_quotes = us_quotes_temp; 258 }
259 } 259 else
260 else 260 {
261 { 261 us_quotes = malloc(strlen(symbol)+1);
262 us_quotes = malloc(strlen(symbol)+1); 262
263 263 if(us_quotes==NULL)
264 if(us_quotes==NULL) 264 {
265 { 265 fprintf(stderr,"Memory allocating error (%s line %d)\n",
266 fprintf(stderr,"Memory allocating error (%s line %d)\n" 266 __FILE__, __LINE__);
267 ,__FILE__, __LINE__); 267 exit(1);
268 exit(1); 268 }
269 } 269 strcpy(us_quotes, symbol);
270 strcpy(us_quotes, symbol); 270 }
271 } 271
272 272 break;
273 break; 273
274 274 case YAHOO_EUROPE:
275 case YAHOO_EUROPE: 275 if (eu_quotes)
276 276 {
277 if (eu_quotes) 277 lgr_eu_quotes = strlen(eu_quotes);
278 { 278 lgr_symbol = strlen(symbol);
279 lgr_eu_quotes = strlen(eu_quotes); 279
280 lgr_symbol = strlen(symbol); 280 eu_quotes_temp = malloc(lgr_eu_quotes + lgr_symbol +2);
281 281 if(eu_quotes_temp==NULL)
282 eu_quotes_temp = malloc(lgr_eu_quotes + lgr_symbol +2); 282 {
283 if(eu_quotes_temp==NULL) 283 fprintf(stderr,"Memory allocating error (%s line %d)\n",
284 { 284 __FILE__, __LINE__);
285 fprintf(stderr,"Memory allocating error (%s line %d)\n" 285 exit(1);
286 ,__FILE__, __LINE__); 286 }
287 exit(1); 287 strcpy(eu_quotes_temp, eu_quotes);
288 } 288 strcat(eu_quotes_temp, "+");
289 strcpy(eu_quotes_temp, eu_quotes); 289 strcat(eu_quotes_temp, symbol);
290 strcat(eu_quotes_temp, "+"); 290
291 strcat(eu_quotes_temp, symbol); 291 free(eu_quotes);
292 292 eu_quotes = eu_quotes_temp;
293 free(eu_quotes); 293 }
294 eu_quotes = eu_quotes_temp; 294 else
295 } 295 {
296 else 296 eu_quotes = malloc(strlen(symbol)+1);
297 { 297 if(eu_quotes==NULL)
298 eu_quotes = malloc(strlen(symbol)+1); 298 {
299 if(eu_quotes==NULL) 299 fprintf(stderr,"Memory allocating error (%s line %d)\n",
300 { 300 __FILE__, __LINE__);
301 fprintf(stderr,"Memory allocating error (%s line %d)\n" 301 exit(1);
302 ,__FILE__, __LINE__); 302 }
303 exit(1); 303 strcpy(eu_quotes, symbol);
304 } 304 }
305 strcpy(eu_quotes, symbol); 305 break;
306 } 306 }
307 break;
308 }
309 } 307 }
310 308
311 free(tok_ptr); 309 free(tok_ptr);
312 310
313 if (us_quotes) 311 if (us_quotes)
314 { 312 {
315 /* Gets us quotes */ 313 /* Gets us quotes */
316 error = download_stocks(us_quotes, &stocks_tmp, YAHOO_US); 314 error = download_stocks(us_quotes, &stocks_tmp, YAHOO_US);
315 free(us_quotes);
317 if (error) return error; 316 if (error) return error;
318 } 317 }
319 318
320 if (eu_quotes) 319 if (eu_quotes)
321 { 320 {
322 /* Gets european quotes */ 321 /* Gets european quotes */
323 error = download_stocks(eu_quotes, &stocks_getted, YAHOO_EUROPE); 322 error = download_stocks(eu_quotes, &stocks_getted, YAHOO_EUROPE);
323 free(eu_quotes);
324 if (error) return error; 324 if (error) return error;
325 325
326 /* concats lists if needed */ 326 /* concats lists if needed */
327 if (stocks_tmp) 327 if (stocks_tmp)
328 { 328 {
329 stocks_tmp2 = stocks_tmp; 329 stocks_tmp2 = stocks_tmp;
330 330
331 while(stocks_tmp2 != NULL) 331 while(stocks_tmp2 != NULL)
332 { 332 {
333 last_stock = stocks_tmp2; 333 last_stock = stocks_tmp2;
334 stocks_tmp2 = next_stock(stocks_tmp2); 334 stocks_tmp2 = next_stock(stocks_tmp2);
335 } 335 }
336 336
337 last_stock->NextStock = stocks_getted; 337 last_stock->NextStock = stocks_getted;
338 stocks_getted->PreviousStock = last_stock; 338 stocks_getted->PreviousStock = last_stock;
339 339
340 } 340 }
341 else (stocks_tmp = stocks_getted); 341 else
342 (stocks_tmp = stocks_getted);
342 } 343 }
343 344
344 *stock_datas = stocks_tmp; 345 *stock_datas = stocks_tmp;
345 346
346 return(0); 347 return(0);
347} 348}
diff --git a/rsync/delta.c b/rsync/delta.c
index 323c079..42f3afb 100644
--- a/rsync/delta.c
+++ b/rsync/delta.c
@@ -1,351 +1,353 @@
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 * 2 *
3 * librsync -- library for network deltas 3 * librsync -- library for network deltas
4 * $Id$ 4 * $Id$
5 * 5 *
6 * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org> 6 * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by 9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or 10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details. 16 * GNU Lesser General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Lesser General Public License 18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 21 */
22 22
23 /* 23 /*
24 | Let's climb to the TOP of that 24 | Let's climb to the TOP of that
25 | MOUNTAIN and think about STRIP 25 | MOUNTAIN and think about STRIP
26 | MINING!! 26 | MINING!!
27 */ 27 */
28 28
29 29
30/* 30/*
31 * delta.c -- Generate in streaming mode an rsync delta given a set of 31 * delta.c -- Generate in streaming mode an rsync delta given a set of
32 * signatures, and a new file. 32 * signatures, and a new file.
33 * 33 *
34 * The size of blocks for signature generation is determined by the 34 * The size of blocks for signature generation is determined by the
35 * block size in the incoming signature. 35 * block size in the incoming signature.
36 * 36 *
37 * To calculate a signature, we need to be able to see at least one 37 * To calculate a signature, we need to be able to see at least one
38 * block of the new file at a time. Once we have that, we calculate 38 * block of the new file at a time. Once we have that, we calculate
39 * its weak signature, and see if there is any block in the signature 39 * its weak signature, and see if there is any block in the signature
40 * hash table that has the same weak sum. If there is one, then we 40 * hash table that has the same weak sum. If there is one, then we
41 * also compute the strong sum of the new block, and cross check that. 41 * also compute the strong sum of the new block, and cross check that.
42 * If they're the same, then we can assume we have a match. 42 * If they're the same, then we can assume we have a match.
43 * 43 *
44 * The final block of the file has to be handled a little differently, 44 * The final block of the file has to be handled a little differently,
45 * because it may be a short match. Short blocks in the signature 45 * because it may be a short match. Short blocks in the signature
46 * don't include their length -- we just allow for the final short 46 * don't include their length -- we just allow for the final short
47 * block of the file to match any block in the signature, and if they 47 * block of the file to match any block in the signature, and if they
48 * have the same checksum we assume they must have the same length. 48 * have the same checksum we assume they must have the same length.
49 * Therefore, when we emit a COPY command, we have to send it with a 49 * Therefore, when we emit a COPY command, we have to send it with a
50 * length that is the same as the block matched, and not the block 50 * length that is the same as the block matched, and not the block
51 * length from the signature. 51 * length from the signature.
52 */ 52 */
53 53
54/* 54/*
55 * Profiling results as of v1.26, 2001-03-18: 55 * Profiling results as of v1.26, 2001-03-18:
56 * 56 *
57 * If everything matches, then we spend almost all our time in 57 * If everything matches, then we spend almost all our time in
58 * rs_mdfour64 and rs_weak_sum, which is unavoidable and therefore a 58 * rs_mdfour64 and rs_weak_sum, which is unavoidable and therefore a
59 * good profile. 59 * good profile.
60 * 60 *
61 * If nothing matches, it is not so good. 61 * If nothing matches, it is not so good.
62 */ 62 */
63 63
64 64
65#include <config_rsync.h> 65#include <config_rsync.h>
66 66
67#include <assert.h> 67#include <assert.h>
68#include <stdlib.h> 68#include <stdlib.h>
69#include <stdio.h> 69#include <stdio.h>
70 70
71#include "rsync.h" 71#include "rsync.h"
72#include "emit.h" 72#include "emit.h"
73#include "stream.h" 73#include "stream.h"
74#include "util.h" 74#include "util.h"
75#include "sumset.h" 75#include "sumset.h"
76#include "job.h" 76#include "job.h"
77#include "trace.h" 77#include "trace.h"
78#include "checksum.h" 78#include "checksum.h"
79#include "search.h" 79#include "search.h"
80#include "types.h" 80#include "types.h"
81 81
82 82
83/** 83/**
84 * Turn this on to make all rolling checksums be checked from scratch. 84 * Turn this on to make all rolling checksums be checked from scratch.
85 */ 85 */
86int rs_roll_paranoia = 0; 86int rs_roll_paranoia = 0;
87 87
88 88
89static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); 89static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *);
90 90
91static rs_result rs_delta_s_deferred_copy(rs_job_t *job); 91static rs_result rs_delta_s_deferred_copy(rs_job_t *job);
92 92
93 93
94 94
95static rs_result rs_delta_s_end(rs_job_t *job) 95static rs_result rs_delta_s_end(rs_job_t *job)
96{ 96{
97 rs_emit_end_cmd(job); 97 rs_emit_end_cmd(job);
98 return RS_DONE; 98 return RS_DONE;
99} 99}
100 100
101 101
102/** 102/**
103 * \brief Get a block of data if possible, and see if it matches. 103 * \brief Get a block of data if possible, and see if it matches.
104 * 104 *
105 * On each call, we try to process all of the input data available on 105 * On each call, we try to process all of the input data available on
106 * the scoop and input buffer. 106 * the scoop and input buffer.
107 */ 107 */
108static rs_result 108static rs_result
109rs_delta_s_scan(rs_job_t *job) 109rs_delta_s_scan(rs_job_t *job)
110{ 110{
111 size_t this_len, avail_len; 111 size_t this_len, avail_len;
112 int is_ending; 112 int is_ending;
113 void *inptr; 113 void *inptr;
114 rs_result result; 114 rs_result result;
115 115
116 rs_job_check(job); 116 rs_job_check(job);
117 117
118 avail_len = rs_scoop_total_avail(job); 118 avail_len = rs_scoop_total_avail(job);
119 this_len = job->block_len; 119 this_len = job->block_len;
120 is_ending = job->stream->eof_in; 120 is_ending = job->stream->eof_in;
121 121
122 /* Now, we have avail_len bytes, and we need to scan through them 122 /* Now, we have avail_len bytes, and we need to scan through them
123 * looking for a match. We'll always end up emitting exactly one 123 * looking for a match. We'll always end up emitting exactly one
124 * command, either a literal or a copy, and after discovering that 124 * command, either a literal or a copy, and after discovering that
125 * we will skip over the appropriate number of bytes. */ 125 * we will skip over the appropriate number of bytes. */
126 if (avail_len == 0) { 126 if (avail_len == 0) {
127 if (is_ending) { 127 if (is_ending) {
128 /* no more delta to do */ 128 /* no more delta to do */
129 job->statefn = rs_delta_s_end; 129 job->statefn = rs_delta_s_end;
130 } 130 }
131 return RS_BLOCKED; 131 return RS_BLOCKED;
132 } 132 }
133 133
134 /* must read at least one block, or give up */ 134 /* must read at least one block, or give up */
135 if ((avail_len < job->block_len) && !is_ending) { 135 if ((avail_len < job->block_len) && !is_ending) {
136 /* we know we won't get it, but we have to try for a whole 136 /* we know we won't get it, but we have to try for a whole
137 * block anyhow so that it gets into the scoop. */ 137 * block anyhow so that it gets into the scoop. */
138 rs_scoop_input(job, job->block_len); 138 rs_scoop_input(job, job->block_len);
139 return RS_BLOCKED; 139 return RS_BLOCKED;
140 } 140 }
141 141
142 result = rs_scoop_readahead(job, avail_len, &inptr); 142 result = rs_scoop_readahead(job, avail_len, &inptr);
143 if (result != RS_DONE) 143 if (result != RS_DONE)
144 return result; 144 return result;
145 145
146 return rs_delta_scan(job, avail_len, inptr); 146 return rs_delta_scan(job, avail_len, inptr);
147} 147}
148 148
149 149
150 150
151/** 151/**
152 * Scan for a matching block in the next \p avail_len bytes of input. 152 * Scan for a matching block in the next \p avail_len bytes of input.
153 * 153 *
154 * If nonmatching data is found, then a LITERAL command will be put in 154 * If nonmatching data is found, then a LITERAL command will be put in
155 * the tube immediately. If matching data is found, then its position 155 * the tube immediately. If matching data is found, then its position
156 * will be saved in the job, and the job state set up to write out a 156 * will be saved in the job, and the job state set up to write out a
157 * COPY command after handling the literal. 157 * COPY command after handling the literal.
158 */ 158 */
159static rs_result 159static rs_result
160rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) 160rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p)
161{ 161{
162 rs_long_t match_where; 162 rs_long_t match_where;
163 int search_pos, end_pos; 163 int search_pos, end_pos;
164 unsigned char *inptr = (unsigned char *) p; 164 unsigned char *inptr = (unsigned char *) p;
165 uint32_t s1 = job->weak_sig & 0xFFFF; 165 uint32_t s1 = job->weak_sig & 0xFFFF;
166 uint32_t s2 = job->weak_sig >> 16; 166 uint32_t s2 = job->weak_sig >> 16;
167 167
168 /* So, we have avail_len bytes of data, and we want to look 168 /* So, we have avail_len bytes of data, and we want to look
169 * through it for a match at some point. It's OK if it's not at 169 * through it for a match at some point. It's OK if it's not at
170 * the start of the available input data. If we're approaching 170 * the start of the available input data. If we're approaching
171 * the end and can't get a match, then we just block and get more 171 * the end and can't get a match, then we just block and get more
172 * later. */ 172 * later. */
173 173
174 /* FIXME: Perhaps we should be working in signed chars for the 174 /* FIXME: Perhaps we should be working in signed chars for the
175 * rolling sum? */ 175 * rolling sum? */
176 176
177 if (job->stream->eof_in) 177 if (job->stream->eof_in)
178 end_pos = avail_len - 1; 178 end_pos = avail_len - 1;
179 else 179 else
180 end_pos = avail_len - job->block_len; 180 end_pos = avail_len - job->block_len;
181 181
182 for (search_pos = 0; search_pos <= end_pos; search_pos++) { 182 for (search_pos = 0; search_pos <= end_pos; search_pos++) {
183 size_t this_len = job->block_len; 183 size_t this_len = job->block_len;
184 184
185 if (search_pos + this_len > avail_len) { 185 if (search_pos + this_len > avail_len) {
186 this_len = avail_len - search_pos; 186 this_len = avail_len - search_pos;
187 rs_trace("block reduced to %d", this_len); 187 rs_trace("block reduced to %d", this_len);
188 } else if (job->have_weak_sig) { 188 } else if (job->have_weak_sig) {
189 unsigned char a = inptr[search_pos + this_len - 1]; 189 unsigned char a = inptr[search_pos + this_len - 1];
190 /* roll in the newly added byte, if any */ 190 /* roll in the newly added byte, if any */
191 s1 += a + RS_CHAR_OFFSET; 191 s1 += a + RS_CHAR_OFFSET;
192 s2 += s1; 192 s2 += s1;
193 193
194 job->weak_sig = (s1 & 0xffff) | (s2 << 16); 194 job->weak_sig = (s1 & 0xffff) | (s2 << 16);
195 } 195 }
196 196
197 if (!job->have_weak_sig) { 197 if (!job->have_weak_sig) {
198 rs_trace("calculate weak sum from scratch"); 198 rs_trace("calculate weak sum from scratch");
199 job->weak_sig = rs_calc_weak_sum(inptr + search_pos, this_len); 199 job->weak_sig = rs_calc_weak_sum(inptr + search_pos, this_len);
200 s1 = job->weak_sig & 0xFFFF; 200 s1 = job->weak_sig & 0xFFFF;
201 s2 = job->weak_sig >> 16; 201 s2 = job->weak_sig >> 16;
202 job->have_weak_sig = 1; 202 job->have_weak_sig = 1;
203 } 203 }
204 204
205 if (rs_roll_paranoia) { 205 if (rs_roll_paranoia) {
206 rs_weak_sum_t verify = rs_calc_weak_sum(inptr + search_pos, this_len); 206 rs_weak_sum_t verify = rs_calc_weak_sum(inptr + search_pos, this_len);
207 if (verify != job->weak_sig) { 207 if (verify != job->weak_sig) {
208 rs_fatal("mismatch between rolled sum %#x and check %#x", 208 rs_fatal("mismatch between rolled sum %#x and check %#x",
209 job->weak_sig, verify); 209 job->weak_sig, verify);
210 } 210 }
211 } 211 }
212 212
213 if (rs_search_for_block(job->weak_sig, inptr + search_pos, this_len, 213 if (rs_search_for_block(job->weak_sig, inptr + search_pos, this_len,
214 job->signature, &job->stats, &match_where)) { 214 job->signature, &job->stats, &match_where)) {
215 /* So, we got a match. Cool. However, there may be 215 /* So, we got a match. Cool. However, there may be
216 * leading unmatched data that we need to flush. Thus we 216 * leading unmatched data that we need to flush. Thus we
217 * set our statefn to be rs_delta_s_deferred_copy so that 217 * set our statefn to be rs_delta_s_deferred_copy so that
218 * we can write out the command later. */ 218 * we can write out the command later. */
219 219
220 rs_trace("matched %.0f bytes at %.0f!", 220 rs_trace("matched %.0f bytes at %.0f!",
221 (double) this_len, (double) match_where); 221 (double) this_len, (double) match_where);
222 job->basis_pos = match_where; 222 job->basis_pos = match_where;
223 job->basis_len = this_len; 223 job->basis_len = this_len;
224 job->statefn = rs_delta_s_deferred_copy; 224 job->statefn = rs_delta_s_deferred_copy;
225 job->have_weak_sig = 0; 225 job->have_weak_sig = 0;
226 break; 226 break;
227 } else { 227 } else {
228 /* advance by one; roll out the byte we just moved over. */ 228 /* advance by one; roll out the byte we just moved over. */
229 unsigned char a = inptr[search_pos]; 229 unsigned char a = inptr[search_pos];
230 unsigned char shift = a + RS_CHAR_OFFSET; 230 unsigned char shift = a + RS_CHAR_OFFSET;
231 231
232 s1 -= shift; 232 s1 -= shift;
233 s2 -= this_len * shift; 233 s2 -= this_len * shift;
234 job->weak_sig = (s1 & 0xffff) | (s2 << 16); 234 job->weak_sig = (s1 & 0xffff) | (s2 << 16);
235 } 235 }
236 } 236 }
237 237
238 if (search_pos > 0) { 238 if (search_pos > 0) {
239 /* We may or may not have found a block, but we know we found 239 /* We may or may not have found a block, but we know we found
240 * some literal data at the start of the buffer. Therefore, 240 * some literal data at the start of the buffer. Therefore,
241 * we have to flush that out before we can continue on and 241 * we have to flush that out before we can continue on and
242 * emit the copy command or keep searching. */ 242 * emit the copy command or keep searching. */
243 243
244 /* FIXME: At the moment, if you call with very short buffers, 244 /* FIXME: At the moment, if you call with very short buffers,
245 * then you will get a series of very short LITERAL commands. 245 * then you will get a series of very short LITERAL commands.
246 * Perhaps this is what you deserve, or perhaps we should try 246 * Perhaps this is what you deserve, or perhaps we should try
247 * to get more readahead and avoid that. */ 247 * to get more readahead and avoid that. */
248 248
249 /* There's some literal data at the start of this window which 249 /* There's some literal data at the start of this window which
250 * we know is not in any block. */ 250 * we know is not in any block. */
251 rs_trace("got %d bytes of literal data", search_pos); 251 rs_trace("got %d bytes of literal data", search_pos);
252 rs_emit_literal_cmd(job, search_pos); 252 rs_emit_literal_cmd(job, search_pos);
253 rs_tube_copy(job, search_pos); 253 rs_tube_copy(job, search_pos);
254 } 254 }
255 255
256 return RS_RUNNING; 256 return RS_RUNNING;
257} 257}
258 258
259 259
260 260
261static rs_result rs_delta_s_deferred_copy(rs_job_t *job) 261static rs_result rs_delta_s_deferred_copy(rs_job_t *job)
262{ 262{
263 if (!job->basis_len) { 263 if (!job->basis_len) {
264 rs_log(RS_LOG_ERR, "somehow got zero basis_len"); 264 rs_log(RS_LOG_ERR, "somehow got zero basis_len");
265 return RS_INTERNAL_ERROR; 265 return RS_INTERNAL_ERROR;
266 } 266 }
267 267
268 rs_emit_copy_cmd(job, job->basis_pos, job->basis_len); 268 rs_emit_copy_cmd(job, job->basis_pos, job->basis_len);
269 rs_scoop_advance(job, job->basis_len); 269 rs_scoop_advance(job, job->basis_len);
270 270
271 job->statefn = rs_delta_s_scan; 271 job->statefn = rs_delta_s_scan;
272 272
273 return RS_RUNNING; 273 return RS_RUNNING;
274} 274}
275 275
276 276
277/** 277/**
278 * \brief State function that does a slack delta containing only 278 * \brief State function that does a slack delta containing only
279 * literal data to recreate the input. 279 * literal data to recreate the input.
280 */ 280 */
281static rs_result rs_delta_s_slack(rs_job_t *job) 281static rs_result rs_delta_s_slack(rs_job_t *job)
282{ 282{
283 rs_buffers_t * const stream = job->stream; 283 rs_buffers_t * const stream = job->stream;
284 size_t avail = stream->avail_in; 284 size_t avail = stream->avail_in;
285 285
286 if (avail) { 286 if (avail) {
287 rs_trace("emit slack delta for %.0f available bytes", (double) avail); 287 rs_trace("emit slack delta for %.0f available bytes", (double) avail);
288 rs_emit_literal_cmd(job, avail); 288 rs_emit_literal_cmd(job, avail);
289 rs_tube_copy(job, avail); 289 rs_tube_copy(job, avail);
290 return RS_RUNNING; 290 return RS_RUNNING;
291 } else { 291 } else {
292 if (rs_job_input_is_ending(job)) { 292 if (rs_job_input_is_ending(job)) {
293 job->statefn = rs_delta_s_end; 293 job->statefn = rs_delta_s_end;
294 return RS_RUNNING; 294 return RS_RUNNING;
295 } else { 295 } else {
296 return RS_BLOCKED; 296 return RS_BLOCKED;
297 } 297 }
298 } 298 }
299} 299}
300 300
301 301
302/** 302/**
303 * State function for writing out the header of the encoding job. 303 * State function for writing out the header of the encoding job.
304 */ 304 */
305static rs_result rs_delta_s_header(rs_job_t *job) 305static rs_result rs_delta_s_header(rs_job_t *job)
306{ 306{
307 rs_emit_delta_header(job); 307 rs_emit_delta_header(job);
308 308
309 if (job->block_len) { 309 if (job->block_len) {
310 if (!job->signature) { 310 if (!job->signature) {
311 rs_error("no signature is loaded into the job"); 311 rs_error("no signature is loaded into the job");
312 return RS_PARAM_ERROR; 312 return RS_PARAM_ERROR;
313 } 313 }
314 job->statefn = rs_delta_s_scan; 314 job->statefn = rs_delta_s_scan;
315 } else { 315 } else {
316 rs_trace("block length is zero for this delta; " 316 rs_trace("block length is zero for this delta; "
317 "therefore using slack deltas"); 317 "therefore using slack deltas");
318 job->statefn = rs_delta_s_slack; 318 job->statefn = rs_delta_s_slack;
319 } 319 }
320 320
321 return RS_RUNNING; 321 return RS_RUNNING;
322} 322}
323 323
324 324
325/** 325/**
326 * Prepare to compute a streaming delta. 326 * Prepare to compute a streaming delta.
327 */ 327 */
328rs_job_t *rs_delta_begin(rs_signature_t *sig) 328rs_job_t *rs_delta_begin(rs_signature_t *sig)
329{ 329{
330 rs_job_t *job; 330 rs_job_t *job;
331 331
332 job = rs_job_new("delta", rs_delta_s_header); 332 job = rs_job_new("delta", rs_delta_s_header);
333 job->signature = sig; 333 job->signature = sig;
334 334
335 if ((job->block_len = sig->block_len) < 0) { 335 if ((job->block_len = sig->block_len) < 0) {
336 rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature", 336 rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature",
337 job->block_len); 337 job->block_len);
338 rs_job_free(job);
338 return NULL; 339 return NULL;
339 } 340 }
340 341
341 job->strong_sum_len = sig->strong_sum_len; 342 job->strong_sum_len = sig->strong_sum_len;
342 if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) { 343 if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) {
343 rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature", 344 rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature",
344 job->strong_sum_len); 345 job->strong_sum_len);
346 rs_job_free(job);
345 return NULL; 347 return NULL;
346 } 348 }
347 349
348 return job; 350 return job;
349} 351}
350 352
351 353