-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/libmpeg3.c | 2 | ||||
-rw-r--r-- | libopie2/opieui/oimageeffect.cpp | 5 | ||||
-rw-r--r-- | library/global.cpp | 30 | ||||
-rw-r--r-- | noncore/apps/opie-reader/Bkmks.cpp | 1 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/Excel.cpp | 4 | ||||
-rw-r--r-- | noncore/apps/zsafe/zsafe.cpp | 57 | ||||
-rw-r--r-- | noncore/comm/keypebble/vncauth.c | 6 | ||||
-rw-r--r-- | noncore/net/ftplib/ftplib.c | 4 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/csv.c | 140 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/currency.c | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/lists.h | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/stocks.c | 189 | ||||
-rw-r--r-- | rsync/delta.c | 2 |
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 | ||
9 | mpeg3_t* mpeg3_new(char *path) | 9 | mpeg3_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 | ||
20 | int mpeg3_delete(mpeg3_t *file) | 20 | int 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 | ||
35 | int mpeg3_check_sig(char *path) | 35 | int 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 | ||
89 | mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) | 89 | mpeg3_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 | ||
230 | mpeg3_t* mpeg3_open(char *path) | 230 | mpeg3_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 | ||
235 | int mpeg3_close(mpeg3_t *file) | 235 | int 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 | ||
242 | int mpeg3_set_cpus(mpeg3_t *file, int cpus) | 242 | int 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 | ||
251 | int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) | 251 | int 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 | ||
260 | int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) | 260 | int 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 | ||
287 | int mpeg3_read_toc(mpeg3_t *file) | 287 | int 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 | ||
303 | int mpeg3_has_audio(mpeg3_t *file) | 303 | int mpeg3_has_audio(mpeg3_t *file) |
304 | { | 304 | { |
305 | return file->has_audio; | 305 | return file->has_audio; |
306 | } | 306 | } |
307 | 307 | ||
308 | int mpeg3_total_astreams(mpeg3_t *file) | 308 | int mpeg3_total_astreams(mpeg3_t *file) |
309 | { | 309 | { |
310 | return file->total_astreams; | 310 | return file->total_astreams; |
311 | } | 311 | } |
312 | 312 | ||
313 | int mpeg3_audio_channels(mpeg3_t *file, | 313 | int 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 | ||
321 | int mpeg3_sample_rate(mpeg3_t *file, | 321 | int 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 | ||
329 | long mpeg3_get_sample(mpeg3_t *file, | 329 | long 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 | ||
337 | int mpeg3_set_sample(mpeg3_t *file, | 337 | int 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 | ||
350 | long mpeg3_audio_samples(mpeg3_t *file, | 350 | long 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 | ||
358 | int mpeg3_has_video(mpeg3_t *file) | 358 | int mpeg3_has_video(mpeg3_t *file) |
359 | { | 359 | { |
360 | return file->has_video; | 360 | return file->has_video; |
361 | } | 361 | } |
362 | 362 | ||
363 | int mpeg3_total_vstreams(mpeg3_t *file) | 363 | int mpeg3_total_vstreams(mpeg3_t *file) |
364 | { | 364 | { |
365 | return file->total_vstreams; | 365 | return file->total_vstreams; |
366 | } | 366 | } |
367 | 367 | ||
368 | int mpeg3_video_width(mpeg3_t *file, | 368 | int 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 | ||
376 | int mpeg3_video_height(mpeg3_t *file, | 376 | int 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 | ||
384 | float mpeg3_frame_rate(mpeg3_t *file, | 384 | float 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 | ||
392 | long mpeg3_video_frames(mpeg3_t *file, | 392 | long 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 | ||
400 | long mpeg3_get_frame(mpeg3_t *file, | 400 | long 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 | ||
408 | int mpeg3_set_frame(mpeg3_t *file, | 408 | int 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 | ||
421 | int mpeg3_seek_percentage(mpeg3_t *file, double percentage) | 421 | int 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 | ||
436 | int mpeg3_previous_frame(mpeg3_t *file, int stream) | 436 | int 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 | ||
445 | double mpeg3_tell_percentage(mpeg3_t *file) | 445 | double 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 | ||
460 | double mpeg3_get_time(mpeg3_t *file) | 460 | double 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 | ||
496 | int mpeg3_end_of_audio(mpeg3_t *file, int stream) | 496 | int 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 | ||
503 | int mpeg3_end_of_video(mpeg3_t *file, int stream) | 503 | int 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 | ||
511 | int mpeg3_read_frame(mpeg3_t *file, | 511 | int 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 | ||
543 | int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream) | 543 | int 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 | ||
558 | int mpeg3_read_yuvframe(mpeg3_t *file, | 558 | int 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 | ||
591 | int mpeg3_read_audio(mpeg3_t *file, | 591 | int 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 | ||
618 | int mpeg3_reread_audio(mpeg3_t *file, | 618 | int 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 | ||
642 | int mpeg3_read_audio_chunk(mpeg3_t *file, | 642 | int 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 | ||
658 | int mpeg3_read_video_chunk(mpeg3_t *file, | 658 | int 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 | ||
7 | Redistribution and use in source and binary forms, with or without | 7 | Redistribution and use in source and binary forms, with or without |
8 | modification, are permitted provided that the following conditions | 8 | modification, are permitted provided that the following conditions |
9 | are met: | 9 | are met: |
10 | 10 | ||
11 | 1. Redistributions of source code must retain the above copyright | 11 | 1. 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. |
13 | 2. Redistributions in binary form must reproduce the above copyright | 13 | 2. 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 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 | THEORY 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 |
26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | THIS 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 | ||
43 | using namespace std; | 43 | using namespace std; |
44 | using namespace Opie::Core; | 44 | using namespace Opie::Core; |
45 | 45 | ||
46 | namespace Opie { | 46 | namespace Opie { |
47 | namespace Ui { | 47 | namespace Ui { |
48 | 48 | ||
49 | inline unsigned int intensityValue(unsigned int color) | 49 | inline 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 | ||
62 | QImage OImageEffect::gradient(const QSize &size, const QColor &ca, | 62 | QImage 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 | ||
324 | QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca, | 324 | QImage 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 | ||
573 | QImage& OImageEffect::intensity(QImage &image, float percent) | 573 | QImage& 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 | ||
637 | QImage& OImageEffect::channelIntensity(QImage &image, float percent, | 637 | QImage& 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 | // |
726 | QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse, | 726 | QImage& 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 |
854 | QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity) | 854 | QImage& 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 |
895 | QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity) | 895 | QImage& 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 | ||
943 | QImage& OImageEffect::blend(QImage &image, float initial_intensity, | 943 | QImage& 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 | // |
1147 | QImage& OImageEffect::blend(QImage &image1, QImage &image2, | 1147 | QImage& 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 | // |
1165 | QImage& OImageEffect::blend(QImage &image1, QImage &image2, | 1165 | QImage& 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 | ||
1238 | unsigned int OImageEffect::lHash(unsigned int c) | 1238 | unsigned 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 | ||
1252 | unsigned int OImageEffect::uHash(unsigned int c) | 1252 | unsigned 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 | ||
1266 | QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing) | 1266 | QImage& 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 | ||
1345 | QImage& OImageEffect::flatten(QImage &img, const QColor &ca, | 1345 | QImage& 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 | ||
1442 | QImage& OImageEffect::fade(QImage &img, float val, const QColor &color) | 1442 | QImage& 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). |
1524 | QImage& OImageEffect::toGray(QImage &img, bool fast) | 1524 | QImage& 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 |
1574 | QImage& OImageEffect::desaturate(QImage &img, float desat) | 1574 | QImage& 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) |
1597 | QImage& OImageEffect::contrast(QImage &img, int c) | 1597 | QImage& 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. |
1647 | QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size) | 1647 | QImage& 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 | ||
1734 | int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) | 1734 | int 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 | ||
1764 | bool OImageEffect::blend( | 1764 | bool 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... |
1821 | bool OImageEffect::blend( | 1821 | bool 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 | ||
1834 | bool OImageEffect::blend( | 1834 | bool 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 | ||
1898 | bool OImageEffect::blendOnLower( | 1898 | bool 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 |
1969 | QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) | 1969 | QImage& 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 | ||
1981 | void OImageEffect::normalize(QImage &img) | 1981 | void 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 | ||
2097 | void OImageEffect::equalize(QImage &img) | 2100 | void 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 | ||
2182 | QImage OImageEffect::sample(QImage &src, int w, int h) | 2185 | QImage 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 | ||
2275 | void OImageEffect::threshold(QImage &img, unsigned int threshold) | 2278 | void 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 | ||
2291 | QImage OImageEffect::charcoal(QImage &src, double factor) | 2294 | QImage 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 | ||
2303 | void OImageEffect::hull(const int x_offset, const int y_offset, | 2306 | void 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 | ||
2383 | QImage OImageEffect::despeckle(QImage &src) | 2386 | QImage 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 | ||
2494 | unsigned int OImageEffect::generateNoise(unsigned int pixel, | 2497 | unsigned 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 | ||
2589 | QImage OImageEffect::addNoise(QImage &src, NoiseType noise_type) | 2592 | QImage 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 | ||
2628 | unsigned int OImageEffect::interpolateColor(QImage *image, double x_offset, | 2631 | unsigned 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 | ||
2719 | QImage OImageEffect::implode(QImage &src, double factor, | 2722 | QImage 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 | ||
2800 | QImage OImageEffect::rotate(QImage &img, RotateDirection r) | 2803 | QImage 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 | ||
2898 | void OImageEffect::solarize(QImage &img, double factor) | 2901 | void 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 | ||
2921 | QImage OImageEffect::spread(QImage &src, unsigned int amount) | 2924 | QImage 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 | ||
2972 | QImage OImageEffect::swirl(QImage &src, double degrees, | 2975 | QImage 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 | ||
3050 | QImage OImageEffect::wave(QImage &src, double amplitude, double wavelength, | 3053 | QImage 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 | ||
3076 | QImage OImageEffect::oilPaint(QImage &src, int radius) | 3079 | QImage 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 | ||
3152 | QImage OImageEffect::edge(QImage &src, double factor) | 3155 | QImage 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 | ||
3249 | QImage OImageEffect::sharpen(QImage &src, double factor) | 3252 | QImage 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 | ||
3400 | QImage OImageEffect::emboss(QImage &src) | 3403 | QImage 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 | ||
3498 | QImage OImageEffect::shade(QImage &src, bool color_shading, double azimuth, | 3501 | QImage 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 | ||
3632 | QImage OImageEffect::blur(QImage &src, double factor) | 3635 | QImage 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) |
3734 | void OImageEffect::contrastHSV(QImage &img, bool sharpen) | 3737 | void 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 | ||
53 | class Emitter : public QObject { | 53 | class Emitter : public QObject { |
54 | Q_OBJECT | 54 | Q_OBJECT |
55 | public: | 55 | public: |
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 | ||
65 | signals: | 65 | signals: |
66 | void setDocument(const QString&); | 66 | void setDocument(const QString&); |
67 | }; | 67 | }; |
68 | 68 | ||
69 | 69 | ||
70 | class StartingAppList : public QObject { | 70 | class StartingAppList : public QObject { |
71 | Q_OBJECT | 71 | Q_OBJECT |
72 | public: | 72 | public: |
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 ); |
75 | private slots: | 75 | private slots: |
76 | void handleNewChannel( const QString &); | 76 | void handleNewChannel( const QString &); |
77 | private: | 77 | private: |
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 | ||
84 | StartingAppList* StartingAppList::appl = 0; | 84 | StartingAppList* StartingAppList::appl = 0; |
85 | 85 | ||
86 | StartingAppList::StartingAppList( QObject *parent, const char* name ) | 86 | StartingAppList::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 | ||
96 | void StartingAppList::add( const QString& name ) | 96 | void 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 | ||
107 | bool StartingAppList::isStarting( const QString name ) | 107 | bool 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 | ||
125 | void StartingAppList::handleNewChannel( const QString & name ) | 125 | void 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 | ||
132 | static bool docDirCreated = FALSE; | 132 | static bool docDirCreated = FALSE; |
133 | static QDawg* fixed_dawg = 0; | 133 | static QDawg* fixed_dawg = 0; |
134 | static QDict<QDawg> *named_dawg = 0; | 134 | static QDict<QDawg> *named_dawg = 0; |
135 | 135 | ||
136 | static QString qpeDir() | 136 | static 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 | ||
143 | static QString dictDir() | 143 | static 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 | */ |
206 | Global::Global() | 206 | Global::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 | */ |
216 | const QDawg& Global::fixedDawg() | 216 | const 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 | */ |
262 | const QDawg& Global::addedDawg() | 262 | const 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 | */ |
273 | const QDawg& Global::dawg(const QString& name) | 273 | const 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 | */ |
298 | void Global::addWords(const QStringList& wordlist) | 298 | void 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 | */ |
311 | void Global::addWords(const QString& dictname, const QStringList& wordlist) | 311 | void 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 | */ |
337 | QString Global::applicationFileName(const QString& appname, const QString& filename) | 337 | QString 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 | */ |
356 | void Global::createDocDir() | 356 | void 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 | */ |
369 | void Global::statusMessage(const QString& message) | 369 | void 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 | */ |
380 | void Global::applyStyle() | 380 | void 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 | */ |
392 | QWidget *Global::shutdown( bool ) | 392 | QWidget *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 | */ |
403 | QWidget *Global::restart( bool ) | 403 | QWidget *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 | */ |
421 | void Global::showInputMethod() | 421 | void 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 | */ |
436 | void Global::hideInputMethod() | 436 | void 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 | */ |
447 | bool Global::isBuiltinCommand( const QString &name ) | 447 | bool 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 | ||
459 | Global::Command* Global::builtin=0; | 459 | Global::Command* Global::builtin=0; |
460 | QGuardedPtr<QWidget> *Global::running=0; | 460 | QGuardedPtr<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 | */ |
471 | void Global::setBuiltinCommands( Command* list ) | 471 | void 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 | */ |
489 | void Global::setDocument( QWidget* receiver, const QString& document ) | 489 | void 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 | */ |
497 | bool Global::terminateBuiltin( const QString& n ) | 497 | bool 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 | */ |
513 | void Global::terminate( const AppLnk* app ) | 513 | void 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 | */ |
532 | void Global::invoke(const QString &c) | 532 | void 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 | */ |
661 | void Global::execute( const QString &c, const QString& document ) | 665 | void 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 | */ |
682 | QString Global::shellQuote(const QString& s) | 686 | QString 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 | */ |
703 | QString Global::stringQuote(const QString& s) | 707 | QString 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 | */ |
723 | void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) | 727 | void 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 | ||
776 | QStringList Global::languageList() | 780 | QStringList 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 | ||
790 | QStringList Global::helpPath() | 794 | QStringList 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 | */ |
816 | bool Global::truncateFile(QFile &f, int size){ | 820 | bool 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 | */ |
835 | QString Global::tempDir() | 839 | QString 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 | ||
11 | const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); | 11 | const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); |
12 | 12 | ||
13 | Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : | 13 | Bkmk::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 | ||
23 | Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) | 23 | Bkmk::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 | ||
28 | Bkmk::Bkmk(const Bkmk& rhs) : | 28 | Bkmk::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 | ||
39 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) | 39 | Bkmk::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 | ||
52 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) | 52 | Bkmk::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 | ||
67 | void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) | 67 | void 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 | ||
96 | Bkmk::~Bkmk() | 96 | Bkmk::~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 | ||
104 | Bkmk& Bkmk::operator=(const Bkmk& rhs) | 104 | Bkmk& 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 | ||
141 | bool Bkmk::operator==(const Bkmk& rhs) | 141 | bool 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 | ||
146 | void Bkmk::setAnno(unsigned char* t, unsigned short len) | 146 | void 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 | ||
167 | void Bkmk::setAnno(tchar* t) | 167 | void 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 | ||
189 | BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) | 189 | BkmkFile::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 | ||
203 | BkmkFile::~BkmkFile() | 203 | BkmkFile::~BkmkFile() |
204 | { | 204 | { |
205 | if (f != NULL) fclose(f); | 205 | if (f != NULL) fclose(f); |
206 | } | 206 | } |
207 | 207 | ||
208 | void BkmkFile::write(const Bkmk& b) | 208 | void 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 | ||
228 | void BkmkFile::write(CList<Bkmk>& bl) | 228 | void 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 | ||
240 | CList<Bkmk>* BkmkFile::readall() | 240 | CList<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 | ||
290 | CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) | 290 | CList<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 | ||
303 | Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) | 303 | Bkmk* 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 | ||
328 | Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) | 328 | Bkmk* 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 | ||
351 | Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) | 352 | Bkmk* 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 | ||
379 | Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) | 380 | Bkmk* 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 | ||
39 | static xfrecord formatter[] = { | 39 | static 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 | ||
78 | int ExcelBook::Integer2Byte(int b1, int b2) | 78 | int 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 | ||
86 | int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) | 86 | int 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 | ||
94 | int ExcelBook::Integer2ByteFile(FILE *f) | 94 | int 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 | ||
102 | float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) | 102 | float 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 | ||
116 | double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) | 116 | double 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 | ||
159 | void ExcelBook::DetectEndian(void) | 159 | void 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 | ||
177 | double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) | 177 | double 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 | ||
201 | bool ExcelBook::OpenFile(char *Filename) | 201 | bool 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 | ||
215 | bool ExcelBook::CloseFile(void) | 215 | bool 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 | ||
244 | void ExcelBook::SeekPosition(int pos) | 244 | void 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 | ||
254 | void ExcelBook::SeekSkip(int pos) | 254 | void 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 | ||
264 | int ExcelBook::FileEOF(void) | 264 | int 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 | ||
270 | int ExcelBook::Get2Bytes(void) | 270 | int 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 | ||
287 | char* ExcelBook::Read(int pos, int length) | 287 | char* 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 | ||
301 | QString ExcelBook::ReadUnicodeChar(int pos, int length) | 301 | QString 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 | ||
318 | QString* ExcelBook::GetString(int num) | 318 | QString* 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 | ||
327 | int ExcelBook::SeekBOF(void) | 327 | int 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 | ||
353 | ExcelBREC* ExcelBook::GetBREC(void) | 353 | ExcelBREC* 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 | ||
366 | ExcelBREC* ExcelBook::PeekBREC(void) | 366 | ExcelBREC* 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 | ||
376 | char* ExcelBook::GetDataOfBREC(ExcelBREC* record) | 376 | char* 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 | ||
385 | void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) | 387 | void 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 | ||
393 | bool ExcelSheet::InitCells() | 395 | bool 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 | ||
405 | void ExcelSheet::Set(int row, int col, ExcelCell* cell) | 407 | void 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 | ||
413 | ExcelCell* ExcelSheet::Get(int row, int col) | 415 | ExcelCell* 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 | ||
421 | int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) | 423 | int 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 | ||
489 | int ExcelBook::ReadSheet(ExcelSheet* sheet) | 491 | int 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 | ||
505 | ExcelSheet* ExcelBook::GetSheet(void) | 507 | ExcelSheet* 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 | ||
525 | void ExcelBook::ParseSheets(void) | 527 | void 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 | ||
574 | void ExcelBook::GetSheets(void) | 576 | void 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 | ||
588 | bool ExcelBook::ParseBook(char *file) | 590 | bool 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 | ||
600 | QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) | 602 | QString 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 | ||
611 | QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) | 613 | QString 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 | ||
626 | void ExcelBook::HandleBoundSheet(ExcelBREC* rec) | 628 | void 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 | ||
652 | void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) | 654 | void 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 | ||
666 | ExcelFormat* ExcelBook::GetFormatting(int xf) | 668 | ExcelFormat* 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 | ||
682 | void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) | 684 | void 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 | ||
743 | char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) | 745 | char* 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 | ||
768 | void ExcelBook::HandleSST(ExcelBREC* rec) | 770 | void 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 | ||
790 | void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec) | 792 | void 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 | ||
801 | ExcelCell* ExcelBook::CellLabel(int row, int col, QString str) | 803 | ExcelCell* 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 | ||
812 | ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d) | 814 | ExcelCell* 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 | ||
824 | QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col) | 826 | QString* 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 | ||
882 | int ExcelBook::CellGetPrecision(double d) | 884 | int 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 | ||
911 | void ExcelBook::CellSetDateFormat(char *d) | 913 | void ExcelBook::CellSetDateFormat(char *d) |
912 | { | 914 | { |
913 | dateformat = QString(d); | 915 | dateformat = QString(d); |
914 | }; | 916 | }; |
915 | 917 | ||
916 | void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record) | 918 | void 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 | ||
940 | void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data) | 942 | void 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 | ||
959 | void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record) | 961 | void 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 | ||
979 | ExcelFormat::ExcelFormat() | 981 | ExcelFormat::ExcelFormat() |
980 | { | 982 | { |
981 | code=0;type=0;format=""; | 983 | code=0;type=0;format=""; |
982 | }; | 984 | }; |
983 | 985 | ||
984 | ExcelFormat::ExcelFormat(int c,int t, QString s) | 986 | ExcelFormat::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 | ||
990 | void ExcelBook::HandleFormat(ExcelBREC* rec) | 992 | void 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 | ||
1007 | void ExcelBook::HandleXF(ExcelBREC* rec) | 1009 | void 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 | ||
1021 | void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record) | 1023 | void 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 | ||
1036 | void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record) | 1038 | void 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 | ||
1080 | QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz) | 1082 | QString 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 | ||
1692 | QString ExcelBook::FindCellName(int row, int col) | 1694 | QString 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> |
25 | using namespace Opie::Core; | 25 | using namespace Opie::Core; |
26 | using namespace Opie::Ui; | 26 | using 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 | ||
73 | const QString APP_KEY = ""; | 73 | const 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 | ||
80 | static const char* const bank_cards_data[] = { | 80 | static 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 | ||
114 | static const char* const passwords_data[] = { | 114 | static 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 | ||
153 | static const char* const software_data[] = { | 153 | static 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 | ||
177 | static const char* const general_data[] = { | 177 | static 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 | */ |
322 | ZSafe::ZSafe( QWidget* parent, const char* name, WFlags fl ) | 322 | ZSafe::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 | ||
534 | const QColor *ZSafe::evenRowColor = &Qt::white; | 534 | const QColor *ZSafe::evenRowColor = &Qt::white; |
535 | // const QColor *ZSafe::oddRowColor = &Qt::lightGray; | 535 | // const QColor *ZSafe::oddRowColor = &Qt::lightGray; |
536 | const QColor *ZSafe::oddRowColor = new QColor(216,240,255); | 536 | const 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 | */ |
541 | ZSafe::~ZSafe() | 541 | ZSafe::~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 |
548 | void ZSafe::slotLoadDocu() | 548 | void ZSafe::slotLoadDocu() |
549 | { | 549 | { |
550 | openDocument (filename); | 550 | openDocument (filename); |
551 | } | 551 | } |
552 | 552 | ||
553 | void ZSafe::deletePwd() | 553 | void 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 | ||
581 | void ZSafe::editPwd() | 581 | void 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 | ||
637 | void ZSafe::newPwd() | 637 | void 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"))); |
658 | retype: | 658 | retype: |
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 | ||
697 | void ZSafe::findPwd() | 697 | void 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 | ||
834 | QString ZSafe::getFieldLabel (QListViewItem *_item, QString field, QString def) | 834 | QString 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 | ||
862 | QString ZSafe::getFieldLabel (QString category, QString field, QString def) | 862 | QString 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 | ||
876 | void ZSafe::showInfo( QListViewItem *_item) | 876 | void 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 | ||
972 | void ZSafe::listViewSelected( QListViewItem *_item) | 972 | void 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 | ||
990 | bool ZSafe::isCategory(QListViewItem *_item) | 990 | bool 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 | ||
1002 | void ZSafe::removeAsciiFile() | 1002 | void 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 | ||
1028 | void ZSafe::writeAllEntries() | 1028 | void 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 | ||
1096 | void ZSafe::readAllEntries() | 1096 | void 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 |
1288 | void ZSafe::writeAllEntries() | 1288 | void 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 | ||
1347 | void ZSafe::readAllEntries() | 1347 | void 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 | ||
1497 | void ZSafe::resume(int) | 1497 | void 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 | ||
1535 | bool ZSafe::openDocument(const char* _filename, const char* ) | 1535 | bool 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 | ||
1759 | int ZSafe::loadInit(const char* _filename, const char *password) | 1759 | int 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 | ||
1840 | int ZSafe::loadEntry(char *entry[FIELD_SIZE]) | 1846 | int 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 | ||
1868 | int ZSafe::loadFinalize(void) | 1874 | int 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 | ||
1875 | bool ZSafe::saveDocument(const char* _filename, | 1881 | bool 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 | ||
2052 | PasswordForm *newPwdDialog; | 2058 | PasswordForm *newPwdDialog; |
2053 | bool newPwdDialogResult = false; | 2059 | bool newPwdDialogResult = false; |
2054 | void ZSafe::setPasswordDialogDone() | 2060 | void ZSafe::setPasswordDialogDone() |
2055 | { | 2061 | { |
2056 | newPwdDialogResult = true; | 2062 | newPwdDialogResult = true; |
2057 | newPwdDialog->close(); | 2063 | newPwdDialog->close(); |
2058 | } | 2064 | } |
2059 | 2065 | ||
2060 | void ZSafe::getDocPassword(QString title) | 2066 | void 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 | ||
2093 | int ZSafe::saveInit(const char *_filename, const char *password) | 2099 | int 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 | ||
2146 | int ZSafe::saveEntry(char *entry[FIELD_SIZE]) | 2140 | int 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 | ||
2202 | int ZSafe::saveFinalize(void) | 2202 | int 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 | ||
2234 | void ZSafe::quitMe () | 2235 | void 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 | ||
2268 | void ZSafe::categoryFieldActivated( const QString& category) | 2269 | void 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 | ||
2274 | void ZSafe::addCategory() | 2275 | void 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 | ||
2434 | void ZSafe::delCategory() | 2435 | void 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 | ||
2477 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) | 2478 | void 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 | ||
2542 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) | 2543 | void 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 | ||
2595 | void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) | 2596 | void 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 | ||
2612 | void ZSafe::editCategory() | 2613 | void 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 | ||
2834 | void ZSafe::cutItem() | 2835 | void 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 | ||
2845 | void ZSafe::copyItem() | 2846 | void 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 |
2857 | void ZSafe::pasteItem() | 2858 | void 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 | ||
2905 | void ZSafe::newDocument() | 2906 | void 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 | ||
2966 | void ZSafe::loadDocument() | 2967 | void 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 | ||
3026 | void ZSafe::saveDocumentAs() | 3027 | void ZSafe::saveDocumentAs() |
3027 | { | 3028 | { |
3028 | 3029 | ||
3029 | QString newFile = zsaveDialog(); | 3030 | QString 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 | ||
3054 | void ZSafe::saveDocumentWithoutPwd() | 3055 | void ZSafe::saveDocumentWithoutPwd() |
3055 | { | 3056 | { |
3056 | saveDocument(filename, FALSE); | 3057 | saveDocument(filename, FALSE); |
3057 | } | 3058 | } |
3058 | 3059 | ||
3059 | void ZSafe::saveDocumentWithPwd() | 3060 | void ZSafe::saveDocumentWithPwd() |
3060 | { | 3061 | { |
3061 | saveDocument(filename, TRUE); | 3062 | saveDocument(filename, TRUE); |
3062 | } | 3063 | } |
3063 | 3064 | ||
3064 | void ZSafe::setExpandFlag() | 3065 | void 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 | ||
3076 | void ZSafe::paintEvent( QPaintEvent * ) | 3077 | void 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 | ||
3087 | void ZSafe::slotRaiseTimer() | 3088 | void 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 | ||
3094 | QPixmap * ZSafe::getPredefinedIcon(QString category) | 3095 | QPixmap * 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 | ||
3110 | void ZSafe::setDocument(const QString& fileref) | 3111 | void 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 | ||
3167 | void ZSafe::ListPressed(int mouse, QListViewItem *item, const QPoint&, int column) { | 3168 | void 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 | ||
3202 | void ZSafe::copyClip( const QString &text) { | 3203 | void 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 | ||
3208 | QString ZSafe::zsaveDialog() { | 3209 | QString 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 | ||
40 | unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; | 40 | unsigned 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 | ||
48 | int | 48 | int |
49 | vncEncryptAndStorePasswd(char *passwd, char *fname) | 49 | vncEncryptAndStorePasswd(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 | ||
90 | char * | 90 | char * |
91 | vncDecryptPasswdFromFile(char *fname) | 91 | vncDecryptPasswdFromFile(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 | ||
122 | void | 126 | void |
123 | vncRandomBytes(unsigned char *bytes) | 127 | vncRandomBytes(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 | ||
139 | void | 143 | void |
140 | vncEncryptBytes(unsigned char *bytes, char *passwd) | 144 | vncEncryptBytes(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 | ||
83 | struct NetBuf { | 83 | struct 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 | ||
101 | static char *version = | 101 | static 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 | ||
104 | GLOBALDEF int ftplib_debug = 0; | 104 | GLOBALDEF 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 | */ |
120 | void *memccpy(void *dest, const void *src, int c, size_t n) | 120 | void *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 | */ |
141 | char *strdup(const char *src) | 141 | char *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 | */ |
157 | static int socket_wait(netbuf *ctl) | 157 | static 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 | */ |
196 | static int readline(char *buf,int max,netbuf *ctl) | 196 | static 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 | */ |
272 | static int writeline(char *buf, int len, netbuf *nData) | 272 | static 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 | */ |
333 | static int readresp(char c, netbuf *nControl) | 333 | static 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 | */ |
368 | GLOBALDEF void FtpInit(void) | 368 | GLOBALDEF 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 | */ |
383 | GLOBALDEF char *FtpLastResponse(netbuf *nControl) | 383 | GLOBALDEF 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 | */ |
395 | GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) | 395 | GLOBALDEF 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 | */ |
543 | GLOBALDEF int FtpOptions(int opt, long val, netbuf *nControl) | 543 | GLOBALDEF 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 | */ |
583 | static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl) | 583 | static 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 | */ |
606 | GLOBALDEF int FtpLogin(const char *user, const char *pass, netbuf *nControl) | 606 | GLOBALDEF 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 | */ |
629 | static int FtpOpenPort(netbuf *nControl, netbuf **nData, int mode, int dir) | 629 | static 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 | */ |
776 | static int FtpAcceptConnection(netbuf *nData, netbuf *nControl) | 776 | static 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 | */ |
848 | GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, | 848 | GLOBALDEF 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 | */ |
919 | GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) | 919 | GLOBALDEF 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 | */ |
952 | GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) | 952 | GLOBALDEF 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 | */ |
983 | GLOBALDEF int FtpClose(netbuf *nData) | 983 | GLOBALDEF 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 | */ |
1023 | GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) | 1023 | GLOBALDEF 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 | */ |
1044 | GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) | 1044 | GLOBALDEF 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 | */ |
1063 | GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) | 1063 | GLOBALDEF 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 | */ |
1080 | GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) | 1080 | GLOBALDEF 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 | */ |
1097 | GLOBALDEF int FtpCDUp(netbuf *nControl) | 1097 | GLOBALDEF 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 | */ |
1109 | GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) | 1109 | GLOBALDEF 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 | */ |
1126 | GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) | 1126 | GLOBALDEF 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 | */ |
1148 | static int FtpXfer(const char *localfile, const char *path, | 1148 | static 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 | */ |
1210 | GLOBALDEF int FtpNlst(const char *outputfile, const char *path, | 1214 | GLOBALDEF 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 | */ |
1221 | GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) | 1225 | GLOBALDEF 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 | */ |
1231 | GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) | 1235 | GLOBALDEF 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 | */ |
1259 | GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) | 1263 | GLOBALDEF 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 | */ |
1279 | GLOBALDEF int FtpGet(const char *outputfile, const char *path, | 1283 | GLOBALDEF 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 | */ |
1290 | GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, | 1294 | GLOBALDEF 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 | */ |
1301 | GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) | 1305 | GLOBALDEF 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 | */ |
1322 | GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) | 1326 | GLOBALDEF 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 | */ |
1339 | GLOBALDEF void FtpQuit(netbuf *nControl) | 1343 | GLOBALDEF 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 | ||
40 | const char *months[12]= | 40 | const 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 | /*****************************************************************************/ |
61 | char *csv_strtok(char *s, char *delim) | 61 | char *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 | /*****************************************************************************/ |
94 | stock *parse_csv_file(char *csv) | 94 | stock *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 | /*****************************************************************************/ |
290 | stock *parse_csv_history_file(char *csv_file) | 334 | stock *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 | /*****************************************************************************/ |
35 | libstocks_return_code get_currency_exchange(char *from, | 35 | libstocks_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 | ||
32 | PUBEXT_LISTS stock *malloc_stock(void); | 32 | PUBEXT_LISTS stock *malloc_stock(void); |
33 | PUBEXT_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 | /* |
38 | s = symbol | 38 | s = symbol |
39 | n = name | 39 | n = name |
40 | l1 = last trade | 40 | l1 = last trade |
41 | d1 = date | 41 | d1 = date |
42 | t1 = time | 42 | t1 = time |
43 | c1 = variation | 43 | c1 = variation |
44 | o = open | 44 | o = open |
45 | h = higher price | 45 | h = higher price |
46 | g = lower price | 46 | g = lower price |
47 | v = volume | 47 | v = volume |
48 | */ | 48 | */ |
49 | 49 | ||
50 | const char yahoo_us_stocks_server[]="finance.yahoo.com"; | 50 | const char yahoo_us_stocks_server[]="finance.yahoo.com"; |
51 | const char yahoo_eu_stocks_server[]="finance.yahoo.com"; | 51 | const 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 | ||
54 | const char yahoo_url_beg[]="/d/quotes.csv?s="; | 54 | const char yahoo_url_beg[]="/d/quotes.csv?s="; |
55 | const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; | 55 | const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; |
56 | 56 | ||
57 | typedef enum { | 57 | typedef 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 |
63 | const char *yahoo_us_ext[YAHOO_US_EXT_NB] = | 63 | const 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 | /*****************************************************************************/ |
83 | yahoo_source find_yahoo_source(char *symbol) | 83 | yahoo_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 | /*****************************************************************************/ |
119 | libstocks_return_code download_stocks(char *stocks, | 119 | libstocks_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 | /*****************************************************************************/ |
191 | libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) | 191 | libstocks_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 | */ |
86 | int rs_roll_paranoia = 0; | 86 | int rs_roll_paranoia = 0; |
87 | 87 | ||
88 | 88 | ||
89 | static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); | 89 | static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); |
90 | 90 | ||
91 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job); | 91 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job); |
92 | 92 | ||
93 | 93 | ||
94 | 94 | ||
95 | static rs_result rs_delta_s_end(rs_job_t *job) | 95 | static 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 | */ |
108 | static rs_result | 108 | static rs_result |
109 | rs_delta_s_scan(rs_job_t *job) | 109 | rs_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 | */ |
159 | static rs_result | 159 | static rs_result |
160 | rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) | 160 | rs_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 | ||
261 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job) | 261 | static 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 | */ |
281 | static rs_result rs_delta_s_slack(rs_job_t *job) | 281 | static 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 | */ |
305 | static rs_result rs_delta_s_header(rs_job_t *job) | 305 | static 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 | */ |
328 | rs_job_t *rs_delta_begin(rs_signature_t *sig) | 328 | rs_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 | ||