Mercurial > geeqie
annotate src/ui_fileops.c @ 274:2710d14f6a28
Fix the "continuous display" of tooltips in the collection view
(before the tooltip delay occured once, then changing icon to icon never hide the
tooltip again, now the tip is displayed shortly after the cursor moved on the icon,
but disappears when moving cursor to another icon).
Display the full path to the file when Show filename text is on (before nothing
was displayed).
When Show filename text is off, behavior is unchanged, the (short) filename is
displayed.
author | zas_ |
---|---|
date | Tue, 08 Apr 2008 21:33:29 +0000 |
parents | 9faf34f047b1 |
children | 9995c5fb202a |
rev | line source |
---|---|
9 | 1 /* |
2 * (SLIK) SimpLIstic sKin functions | |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
3 * (C) 2006 John Ellis |
9 | 4 * |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
12 #ifdef HAVE_CONFIG_H | |
13 # include "config.h" | |
14 #endif | |
15 | |
16 #include <pwd.h> | |
17 #include <stdio.h> | |
18 #include <stdlib.h> | |
19 #include <string.h> | |
20 #include <unistd.h> | |
21 #include <sys/param.h> | |
22 #include <dirent.h> | |
23 #include <utime.h> | |
24 | |
25 #include <glib.h> | |
26 #include <gtk/gtk.h> /* for locale warning dialog */ | |
27 | |
138 | 28 #include "gqview.h" |
9 | 29 #include "ui_fileops.h" |
30 | |
31 #include "ui_utildlg.h" /* for locale warning dialog */ | |
32 | |
33 /* | |
34 *----------------------------------------------------------------------------- | |
35 * generic file information and manipulation routines (public) | |
36 *----------------------------------------------------------------------------- | |
37 */ | |
38 | |
39 /* file sorting method (case) */ | |
40 gint file_sort_case_sensitive = FALSE; | |
41 | |
42 | |
43 void print_term(const gchar *text_utf8) | |
44 { | |
45 gchar *text_l; | |
46 | |
47 text_l = g_locale_from_utf8(text_utf8, -1, NULL, NULL, NULL); | |
48 printf((text_l) ? text_l : text_utf8); | |
49 g_free(text_l); | |
50 } | |
51 | |
52 static void encoding_dialog(const gchar *path); | |
53 | |
54 static gint encoding_dialog_idle(gpointer data) | |
55 { | |
56 gchar *path = data; | |
57 | |
58 encoding_dialog(path); | |
59 g_free(path); | |
60 | |
61 return FALSE; | |
62 } | |
63 | |
64 static gint encoding_dialog_delay(gpointer data) | |
65 { | |
66 g_idle_add(encoding_dialog_idle, data); | |
67 | |
68 return 0; | |
69 } | |
70 | |
71 static void encoding_dialog(const gchar *path) | |
72 { | |
73 static gint warned_user = FALSE; | |
74 GenericDialog *gd; | |
75 GString *string; | |
76 const gchar *lc; | |
77 const gchar *bf; | |
78 | |
79 /* check that gtk is initialized (loop is level > 0) */ | |
80 if (gtk_main_level() == 0) | |
81 { | |
82 /* gtk not initialized */ | |
83 gtk_init_add(encoding_dialog_delay, g_strdup(path)); | |
84 return; | |
85 } | |
86 | |
87 if (warned_user) return; | |
88 warned_user = TRUE; | |
89 | |
90 lc = getenv("LANG"); | |
91 bf = getenv("G_BROKEN_FILENAMES"); | |
92 warned_user = TRUE; | |
93 | |
94 string = g_string_new(""); | |
95 g_string_append(string, "One or more filenames are not encoded with the preferred locale character set.\n"); | |
96 g_string_append_printf(string, "Operations on, and display of these files with %s may not succeed.\n\n", PACKAGE); | |
97 g_string_append(string, "If your filenames are not encoded in utf-8, try setting\n"); | |
98 g_string_append(string, "the environment variable G_BROKEN_FILENAMES=1\n"); | |
99 g_string_append_printf(string, "It appears G_BROKEN_FILENAMES is %s%s\n\n", | |
100 (bf) ? "set to " : "not set.", (bf) ? bf : ""); | |
101 g_string_append_printf(string, "The locale appears to be set to \"%s\"\n(set by the LANG environment variable)\n", (lc) ? lc : "undefined"); | |
102 if (lc && (strstr(lc, "UTF-8") || strstr(lc, "utf-8"))) | |
103 { | |
104 gchar *name; | |
105 name = g_convert(path, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL); | |
106 string = g_string_append(string, "\nPreferred encoding appears to be UTF-8, however the file:\n"); | |
107 g_string_append_printf(string, "\"%s\"\n%s encoded in valid UTF-8.\n", | |
108 (name) ? name : "[name not displayable]", | |
109 (g_utf8_validate(path, -1, NULL)) ? "is": "is NOT"); | |
110 g_free(name); | |
111 } | |
112 | |
113 gd = generic_dialog_new("Filename encoding locale mismatch", | |
254
9faf34f047b1
Make the wmclass value unique among the code by defining
zas_
parents:
138
diff
changeset
|
114 GQ_WMCLASS, "locale warning", NULL, TRUE, NULL, NULL); |
9 | 115 generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE); |
116 | |
117 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING, | |
118 "Filename encoding locale mismatch", string->str); | |
119 | |
120 gtk_widget_show(gd->dialog); | |
121 | |
122 g_string_free(string, TRUE); | |
123 } | |
124 | |
125 gchar *path_to_utf8(const gchar *path) | |
126 { | |
127 gchar *utf8; | |
128 GError *error = NULL; | |
129 | |
130 if (!path) return NULL; | |
131 | |
132 utf8 = g_filename_to_utf8(path, -1, NULL, NULL, &error); | |
133 if (error) | |
134 { | |
135 printf("Unable to convert filename to UTF-8:\n%s\n%s\n", path, error->message); | |
136 g_error_free(error); | |
137 encoding_dialog(path); | |
138 } | |
139 if (!utf8) | |
140 { | |
141 /* just let it through, but bad things may happen */ | |
142 utf8 = g_strdup(path); | |
143 } | |
144 | |
145 return utf8; | |
146 } | |
147 | |
148 gchar *path_from_utf8(const gchar *utf8) | |
149 { | |
150 gchar *path; | |
151 GError *error = NULL; | |
152 | |
153 if (!utf8) return NULL; | |
154 | |
155 path = g_filename_from_utf8(utf8, -1, NULL, NULL, &error); | |
156 if (error) | |
157 { | |
158 printf("Unable to convert filename to locale from UTF-8:\n%s\n%s\n", utf8, error->message); | |
159 g_error_free(error); | |
160 } | |
161 if (!path) | |
162 { | |
163 /* if invalid UTF-8, text probaby still in original form, so just copy it */ | |
164 path = g_strdup(utf8); | |
165 } | |
166 | |
167 return path; | |
168 } | |
169 | |
170 /* first we try the HOME environment var, if that doesn't work, we try getpwuid(). */ | |
171 const gchar *homedir(void) | |
172 { | |
173 static gchar *home = NULL; | |
174 | |
175 if (!home) | |
176 { | |
177 home = path_to_utf8(getenv("HOME")); | |
178 } | |
179 if (!home) | |
180 { | |
181 struct passwd *pw = getpwuid(getuid()); | |
182 if (pw) home = path_to_utf8(pw->pw_dir); | |
183 } | |
184 | |
185 return home; | |
186 } | |
187 | |
188 gint stat_utf8(const gchar *s, struct stat *st) | |
189 { | |
190 gchar *sl; | |
191 gint ret; | |
192 | |
193 if (!s) return FALSE; | |
194 sl = path_from_utf8(s); | |
195 ret = (stat(sl, st) == 0); | |
196 g_free(sl); | |
197 | |
198 return ret; | |
199 } | |
200 | |
40
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
201 gint lstat_utf8(const gchar *s, struct stat *st) |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
202 { |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
203 gchar *sl; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
204 gint ret; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
205 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
206 if (!s) return FALSE; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
207 sl = path_from_utf8(s); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
208 ret = (lstat(sl, st) == 0); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
209 g_free(sl); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
210 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
211 return ret; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
212 } |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
213 |
9 | 214 gint isname(const gchar *s) |
215 { | |
216 struct stat st; | |
217 | |
218 return stat_utf8(s, &st); | |
219 } | |
220 | |
221 gint isfile(const gchar *s) | |
222 { | |
223 struct stat st; | |
224 | |
225 return (stat_utf8(s, &st) && S_ISREG(st.st_mode)); | |
226 } | |
227 | |
228 gint isdir(const gchar *s) | |
229 { | |
230 struct stat st; | |
231 | |
232 return (stat_utf8(s ,&st) && S_ISDIR(st.st_mode)); | |
233 } | |
234 | |
40
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
235 gint islink(const gchar *s) |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
236 { |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
237 struct stat st; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
238 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
239 return (lstat_utf8(s ,&st) && S_ISLNK(st.st_mode)); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
240 } |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
241 |
9 | 242 gint64 filesize(const gchar *s) |
243 { | |
244 struct stat st; | |
245 | |
246 if (!stat_utf8(s, &st)) return 0; | |
247 return (gint)st.st_size; | |
248 } | |
249 | |
250 time_t filetime(const gchar *s) | |
251 { | |
252 struct stat st; | |
253 | |
254 if (!stat_utf8(s, &st)) return 0; | |
255 return st.st_mtime; | |
256 } | |
257 | |
258 gint filetime_set(const gchar *s, time_t tval) | |
259 { | |
260 gint ret = FALSE; | |
261 | |
262 if (tval > 0) | |
263 { | |
264 struct utimbuf ut; | |
265 gchar *sl; | |
266 | |
267 ut.actime = ut.modtime = tval; | |
268 | |
269 sl = path_from_utf8(s); | |
270 ret = (utime(sl, &ut) == 0); | |
271 g_free(sl); | |
272 } | |
273 | |
274 return ret; | |
275 } | |
276 | |
277 gint access_file(const gchar *s, int mode) | |
278 { | |
279 gchar *sl; | |
280 gint ret; | |
281 | |
282 if (!s) return FALSE; | |
283 | |
284 sl = path_from_utf8(s); | |
285 ret = (access(sl, mode) == 0); | |
286 g_free(sl); | |
287 | |
288 return ret; | |
289 } | |
290 | |
291 gint unlink_file(const gchar *s) | |
292 { | |
293 gchar *sl; | |
294 gint ret; | |
295 | |
296 if (!s) return FALSE; | |
297 | |
298 sl = path_from_utf8(s); | |
299 ret = (unlink(sl) == 0); | |
300 g_free(sl); | |
301 | |
302 return ret; | |
303 } | |
304 | |
305 gint symlink_utf8(const gchar *source, const gchar *target) | |
306 { | |
307 gchar *sl; | |
308 gchar *tl; | |
309 gint ret; | |
310 | |
311 if (!source || !target) return FALSE; | |
312 | |
313 sl = path_from_utf8(source); | |
314 tl = path_from_utf8(target); | |
315 | |
316 ret = (symlink(sl, tl) == 0); | |
317 | |
318 g_free(sl); | |
319 g_free(tl); | |
320 | |
321 return ret; | |
322 } | |
323 | |
324 gint mkdir_utf8(const gchar *s, int mode) | |
325 { | |
326 gchar *sl; | |
327 gint ret; | |
328 | |
329 if (!s) return FALSE; | |
330 | |
331 sl = path_from_utf8(s); | |
332 ret = (mkdir(sl, mode) == 0); | |
333 g_free(sl); | |
334 return ret; | |
335 } | |
336 | |
337 gint rmdir_utf8(const gchar *s) | |
338 { | |
339 gchar *sl; | |
340 gint ret; | |
341 | |
342 if (!s) return FALSE; | |
343 | |
344 sl = path_from_utf8(s); | |
345 ret = (rmdir(sl) == 0); | |
346 g_free(sl); | |
347 | |
348 return ret; | |
349 } | |
350 | |
351 gint copy_file_attributes(const gchar *s, const gchar *t, gint perms, gint mtime) | |
352 { | |
353 struct stat st; | |
354 gchar *sl, *tl; | |
355 gint ret = FALSE; | |
356 | |
357 if (!s || !t) return FALSE; | |
358 | |
359 sl = path_from_utf8(s); | |
360 tl = path_from_utf8(t); | |
361 | |
362 if (stat(sl, &st) == 0) | |
363 { | |
364 struct utimbuf tb; | |
365 | |
366 ret = TRUE; | |
367 | |
368 /* set the dest file attributes to that of source (ignoring errors) */ | |
369 | |
370 if (perms && chown(tl, st.st_uid, st.st_gid) < 0) ret = FALSE; | |
371 if (perms && chmod(tl, st.st_mode) < 0) ret = FALSE; | |
372 | |
373 tb.actime = st.st_atime; | |
374 tb.modtime = st.st_mtime; | |
375 if (mtime && utime(tl, &tb) < 0) ret = FALSE; | |
376 } | |
377 | |
378 g_free(sl); | |
379 g_free(tl); | |
380 | |
381 return ret; | |
382 } | |
383 | |
384 /* paths are in filesystem encoding */ | |
385 static gint hard_linked(const gchar *a, const gchar *b) | |
386 { | |
387 struct stat sta; | |
388 struct stat stb; | |
389 | |
390 if (stat(a, &sta) != 0 || stat(b, &stb) != 0) return FALSE; | |
391 | |
392 return (sta.st_dev == stb.st_dev && | |
393 sta.st_ino == stb.st_ino); | |
394 } | |
395 | |
396 gint copy_file(const gchar *s, const gchar *t) | |
397 { | |
398 FILE *fi = NULL; | |
399 FILE *fo = NULL; | |
400 gchar *sl, *tl; | |
401 gchar buf[4096]; | |
402 gint b; | |
403 | |
404 sl = path_from_utf8(s); | |
405 tl = path_from_utf8(t); | |
406 | |
407 if (hard_linked(sl, tl)) | |
408 { | |
409 g_free(sl); | |
410 g_free(tl); | |
411 return TRUE; | |
412 } | |
413 | |
414 fi = fopen(sl, "rb"); | |
415 if (fi) | |
416 { | |
417 fo = fopen(tl, "wb"); | |
418 if (!fo) | |
419 { | |
420 fclose(fi); | |
421 fi = NULL; | |
422 } | |
423 } | |
424 | |
425 g_free(sl); | |
426 g_free(tl); | |
427 | |
428 if (!fi || !fo) return FALSE; | |
429 | |
430 while((b = fread(buf, sizeof(char), 4096, fi)) && b != 0) | |
431 { | |
432 if (fwrite(buf, sizeof(char), b, fo) != b) | |
433 { | |
434 fclose(fi); | |
435 fclose(fo); | |
436 return FALSE; | |
437 } | |
438 } | |
439 | |
440 fclose(fi); | |
441 fclose(fo); | |
442 | |
443 copy_file_attributes(s, t, TRUE, TRUE); | |
444 | |
445 return TRUE; | |
446 } | |
447 | |
448 gint move_file(const gchar *s, const gchar *t) | |
449 { | |
450 gchar *sl, *tl; | |
451 gint ret = TRUE; | |
452 | |
453 if (!s || !t) return FALSE; | |
454 | |
455 sl = path_from_utf8(s); | |
456 tl = path_from_utf8(t); | |
457 if (rename(sl, tl) < 0) | |
458 { | |
459 /* this may have failed because moving a file across filesystems | |
460 was attempted, so try copy and delete instead */ | |
461 if (copy_file(s, t)) | |
462 { | |
463 if (unlink(sl) < 0) | |
464 { | |
465 /* err, now we can't delete the source file so return FALSE */ | |
466 ret = FALSE; | |
467 } | |
468 } | |
469 else | |
470 { | |
471 ret = FALSE; | |
472 } | |
473 } | |
474 g_free(sl); | |
475 g_free(tl); | |
476 | |
477 return ret; | |
478 } | |
479 | |
480 gint rename_file(const gchar *s, const gchar *t) | |
481 { | |
482 gchar *sl, *tl; | |
483 gint ret; | |
484 | |
485 if (!s || !t) return FALSE; | |
486 | |
487 sl = path_from_utf8(s); | |
488 tl = path_from_utf8(t); | |
489 ret = (rename(sl, tl) == 0); | |
490 g_free(sl); | |
491 g_free(tl); | |
492 | |
493 return ret; | |
494 } | |
495 | |
496 gchar *get_current_dir(void) | |
497 { | |
498 gchar *pathl; | |
499 gchar *path8; | |
500 | |
501 pathl = g_get_current_dir(); | |
502 path8 = path_to_utf8(pathl); | |
503 g_free(pathl); | |
504 | |
505 return path8; | |
506 } | |
507 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
508 static gint path_list_real(const gchar *path, GList **files, GList **dirs, |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
509 gint follow_links) |
9 | 510 { |
511 DIR *dp; | |
512 struct dirent *dir; | |
513 GList *f_list = NULL; | |
514 GList *d_list = NULL; | |
515 gchar *pathl; | |
516 | |
517 if (!path) return FALSE; | |
518 | |
519 pathl = path_from_utf8(path); | |
520 dp = opendir(pathl); | |
521 if (!dp) | |
522 { | |
523 /* dir not found */ | |
524 g_free(pathl); | |
525 return FALSE; | |
526 } | |
527 | |
528 /* root dir fix */ | |
529 if (pathl[0] == '/' && pathl[1] == '\0') | |
530 { | |
531 g_free(pathl); | |
532 pathl = g_strdup(""); | |
533 } | |
534 | |
535 while ((dir = readdir(dp)) != NULL) | |
536 { | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
537 struct stat st_buf; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
538 gchar *name; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
539 gchar *filepath; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
540 gint result; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
541 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
542 name = dir->d_name; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
543 filepath = g_strconcat(pathl, "/", name, NULL); |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
544 |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
545 if (follow_links) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
546 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
547 result = stat(filepath, &st_buf); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
548 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
549 else |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
550 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
551 result = lstat(filepath, &st_buf); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
552 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
553 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
554 if (result == 0) |
9 | 555 { |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
556 gchar *path8; |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
557 gchar *name8; |
9 | 558 |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
559 name8 = path_to_utf8(name); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
560 path8 = g_strconcat(path, "/", name8, NULL); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
561 g_free(name8); |
9 | 562 |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
563 if (dirs && S_ISDIR(st_buf.st_mode) && |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
564 !(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ) |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
565 { |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
566 d_list = g_list_prepend(d_list, path8); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
567 path8 = NULL; |
9 | 568 } |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
569 else if (files && |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
570 (S_ISREG(st_buf.st_mode) || (!follow_links && S_ISLNK(st_buf.st_mode))) ) |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
571 { |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
572 f_list = g_list_prepend(f_list, path8); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
573 path8 = NULL; |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
574 } |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
575 g_free(path8); |
9 | 576 } |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
577 |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
578 g_free(filepath); |
9 | 579 } |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
580 |
9 | 581 closedir(dp); |
582 | |
583 g_free(pathl); | |
584 | |
585 if (dirs) *dirs = g_list_reverse(d_list); | |
586 if (files) *files = g_list_reverse(f_list); | |
587 | |
588 return TRUE; | |
589 } | |
590 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
591 gint path_list(const gchar *path, GList **files, GList **dirs) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
592 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
593 return path_list_real(path, files, dirs, TRUE); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
594 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
595 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
596 gint path_list_lstat(const gchar *path, GList **files, GList **dirs) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
597 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
598 return path_list_real(path, files, dirs, FALSE); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
599 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
600 |
9 | 601 void path_list_free(GList *list) |
602 { | |
603 g_list_foreach(list, (GFunc)g_free, NULL); | |
604 g_list_free(list); | |
605 } | |
606 | |
607 GList *path_list_copy(GList *list) | |
608 { | |
609 GList *new_list = NULL; | |
610 GList *work; | |
611 | |
612 work = list; | |
613 while (work) | |
614 { | |
615 gchar *path; | |
616 | |
617 path = work->data; | |
618 work = work->next; | |
619 | |
620 new_list = g_list_prepend(new_list, g_strdup(path)); | |
621 } | |
622 | |
623 return g_list_reverse(new_list); | |
624 } | |
625 | |
626 long checksum_simple(const gchar *path) | |
627 { | |
628 gchar *path8; | |
629 FILE *f; | |
630 long sum = 0; | |
631 gint c; | |
632 | |
633 path8 = path_from_utf8(path); | |
634 f = fopen(path8, "r"); | |
635 g_free(path8); | |
636 if (!f) return -1; | |
637 | |
638 while((c = fgetc(f)) != EOF) | |
639 { | |
640 sum += c; | |
641 } | |
642 | |
643 fclose(f); | |
644 | |
645 return sum; | |
646 } | |
647 | |
648 gchar *unique_filename(const gchar *path, const gchar *ext, const gchar *divider, gint pad) | |
649 { | |
650 gchar *unique; | |
651 gint n = 1; | |
652 | |
653 if (!ext) ext = ""; | |
654 if (!divider) divider = ""; | |
655 | |
656 unique = g_strconcat(path, ext, NULL); | |
657 while (isname(unique)) | |
658 { | |
659 g_free(unique); | |
660 if (pad) | |
661 { | |
662 unique = g_strdup_printf("%s%s%03d%s", path, divider, n, ext); | |
663 } | |
664 else | |
665 { | |
666 unique = g_strdup_printf("%s%s%d%s", path, divider, n, ext); | |
667 } | |
668 n++; | |
669 if (n > 999) | |
670 { | |
671 /* well, we tried */ | |
672 g_free(unique); | |
673 return NULL; | |
674 } | |
675 } | |
676 | |
677 return unique; | |
678 } | |
679 | |
680 gchar *unique_filename_simple(const gchar *path) | |
681 { | |
682 gchar *unique; | |
683 const gchar *name; | |
684 const gchar *ext; | |
685 | |
686 if (!path) return NULL; | |
687 | |
688 name = filename_from_path(path); | |
689 if (!name) return NULL; | |
690 | |
691 ext = extension_from_path(name); | |
692 | |
693 if (!ext) | |
694 { | |
695 unique = unique_filename(path, NULL, "_", TRUE); | |
696 } | |
697 else | |
698 { | |
699 gchar *base; | |
700 | |
701 base = remove_extension_from_path(path); | |
702 unique = unique_filename(base, ext, "_", TRUE); | |
703 g_free(base); | |
704 } | |
705 | |
706 return unique; | |
707 } | |
708 | |
709 const gchar *filename_from_path(const gchar *path) | |
710 { | |
711 const gchar *base; | |
712 | |
713 if (!path) return NULL; | |
714 | |
715 base = strrchr(path, '/'); | |
716 if (base) return base + 1; | |
717 | |
718 return path; | |
719 } | |
720 | |
721 gchar *remove_level_from_path(const gchar *path) | |
722 { | |
723 gchar *new_path; | |
724 const gchar *ptr = path; | |
725 gint p; | |
726 | |
727 if (!path) return NULL; | |
728 | |
729 p = strlen(path) - 1; | |
730 if (p < 0) return NULL; | |
731 while(ptr[p] != '/' && p > 0) p--; | |
732 if (p == 0 && ptr[p] == '/') p++; | |
733 new_path = g_strndup(path, (guint)p); | |
734 return new_path; | |
735 } | |
736 | |
737 gchar *concat_dir_and_file(const gchar *base, const gchar *name) | |
738 { | |
739 if (!base || !name) return NULL; | |
740 | |
741 if (strcmp(base, "/") == 0) return g_strconcat(base, name, NULL); | |
742 | |
743 return g_strconcat(base, "/", name, NULL); | |
744 } | |
745 | |
746 const gchar *extension_from_path(const gchar *path) | |
747 { | |
748 if (!path) return NULL; | |
749 return strrchr(path, '.'); | |
750 } | |
751 | |
752 gint file_extension_match(const gchar *path, const gchar *ext) | |
753 { | |
754 gint p; | |
755 gint e; | |
756 | |
757 if (!path) return FALSE; | |
758 if (!ext) return TRUE; | |
759 | |
760 p = strlen(path); | |
761 e = strlen(ext); | |
762 | |
763 return (p > e && strncasecmp(path + p - e, ext, e) == 0); | |
764 } | |
765 | |
766 gchar *remove_extension_from_path(const gchar *path) | |
767 { | |
768 gchar *new_path; | |
769 const gchar *ptr = path; | |
770 gint p; | |
771 | |
772 if (!path) return NULL; | |
773 if (strlen(path) < 2) return g_strdup(path); | |
774 | |
775 p = strlen(path) - 1; | |
776 while(ptr[p] != '.' && p > 0) p--; | |
777 if (p == 0) p = strlen(path) - 1; | |
778 new_path = g_strndup(path, (guint)p); | |
779 return new_path; | |
780 } | |
781 | |
782 void parse_out_relatives(gchar *path) | |
783 { | |
784 gint s, t; | |
785 | |
786 if (!path) return; | |
787 | |
788 s = t = 0; | |
789 | |
790 while (path[s] != '\0') | |
791 { | |
792 if (path[s] == '/' && path[s+1] == '.' && (path[s+2] == '/' || path[s+2] == '\0') ) | |
793 { | |
794 s += 2; | |
795 } | |
796 else if (path[s] == '/' && path[s+1] == '.' && path[s+2] == '.' && (path[s+3] == '/' || path[s+3] == '\0') ) | |
797 { | |
798 s += 3; | |
799 if (t > 0) t--; | |
800 while (path[t] != '/' && t > 0) t--; | |
801 } | |
802 else | |
803 { | |
804 if (s != t) path[t] = path[s]; | |
805 t++; | |
806 s++; | |
807 } | |
808 } | |
809 if (t == 0 && path[t] == '/') t++; | |
810 if (t > 1 && path[t-1] == '/') t--; | |
811 path[t] = '\0'; | |
812 } | |
813 | |
814 gint file_in_path(const gchar *name) | |
815 { | |
816 gchar *path; | |
817 gchar *namel; | |
818 gint p, l; | |
819 gint ret = FALSE; | |
820 | |
821 if (!name) return FALSE; | |
822 path = g_strdup(getenv("PATH")); | |
823 if (!path) return FALSE; | |
824 namel = path_from_utf8(name); | |
825 | |
826 p = 0; | |
827 l = strlen(path); | |
828 while (p < l && !ret) | |
829 { | |
830 gchar *f; | |
831 gint e = p; | |
832 while (path[e] != ':' && path[e] != '\0') e++; | |
833 path[e] = '\0'; | |
834 e++; | |
835 f = g_strconcat(path + p, "/", namel, NULL); | |
836 if (isfile(f)) ret = TRUE; | |
837 g_free(f); | |
838 p = e; | |
839 } | |
840 g_free(namel); | |
841 g_free(path); | |
842 | |
843 return ret; | |
844 } | |
845 |