comparison src/pan-util.c @ 105:de64a683d5d0

Thu Nov 9 17:43:06 2006 John Ellis <johne@verizon.net> * pan-view.c: Break this monstrosity of code into smaller files. * pan-calendar.c, pan-folder.c, pan-grid.c, pan-timeline.c: Move the layout types into their own files (for now flower is with folder tree). * pan-item.c: PanItem creation, drawing, actions, and maintenance. * pan-types.h: Defines, data types, function prototypes. * pan-util.c: Various utilities. * src/Makefile.am: Add new files above.
author gqview
date Thu, 09 Nov 2006 22:53:11 +0000
parents
children 71e1ebee420e
comparison
equal deleted inserted replaced
104:8d358a53146e 105:de64a683d5d0
1 /*
2 * GQview
3 * (C) 2006 John Ellis
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 #include "gqview.h"
13 #include "pan-types.h"
14
15 #include "ui_fileops.h"
16
17
18 /*
19 *-----------------------------------------------------------------------------
20 * date functions
21 *-----------------------------------------------------------------------------
22 */
23
24 gint pan_date_compare(time_t a, time_t b, PanDateLengthType length)
25 {
26 struct tm ta;
27 struct tm tb;
28
29 if (length == PAN_DATE_LENGTH_EXACT) return (a == b);
30
31 if (!localtime_r(&a, &ta) ||
32 !localtime_r(&b, &tb)) return FALSE;
33
34 if (ta.tm_year != tb.tm_year) return FALSE;
35 if (length == PAN_DATE_LENGTH_YEAR) return TRUE;
36
37 if (ta.tm_mon != tb.tm_mon) return FALSE;
38 if (length == PAN_DATE_LENGTH_MONTH) return TRUE;
39
40 if (length == PAN_DATE_LENGTH_WEEK) return (ta.tm_yday / 7 == tb.tm_yday / 7);
41
42 if (ta.tm_mday != tb.tm_mday) return FALSE;
43 if (length == PAN_DATE_LENGTH_DAY) return TRUE;
44
45 return (ta.tm_hour == tb.tm_hour);
46 }
47
48 gint pan_date_value(time_t d, PanDateLengthType length)
49 {
50 struct tm td;
51
52 if (!localtime_r(&d, &td)) return -1;
53
54 switch (length)
55 {
56 case PAN_DATE_LENGTH_DAY:
57 return td.tm_mday;
58 break;
59 case PAN_DATE_LENGTH_WEEK:
60 return td.tm_wday;
61 break;
62 case PAN_DATE_LENGTH_MONTH:
63 return td.tm_mon + 1;
64 break;
65 case PAN_DATE_LENGTH_YEAR:
66 return td.tm_year + 1900;
67 break;
68 case PAN_DATE_LENGTH_EXACT:
69 default:
70 break;
71 }
72
73 return -1;
74 }
75
76 gchar *pan_date_value_string(time_t d, PanDateLengthType length)
77 {
78 struct tm td;
79 gchar buf[128];
80 gchar *format = NULL;
81
82 if (!localtime_r(&d, &td)) return g_strdup("");
83
84 switch (length)
85 {
86 case PAN_DATE_LENGTH_DAY:
87 return g_strdup_printf("%d", td.tm_mday);
88 break;
89 case PAN_DATE_LENGTH_WEEK:
90 format = "%A %e";
91 break;
92 case PAN_DATE_LENGTH_MONTH:
93 format = "%B %Y";
94 break;
95 case PAN_DATE_LENGTH_YEAR:
96 return g_strdup_printf("%d", td.tm_year + 1900);
97 break;
98 case PAN_DATE_LENGTH_EXACT:
99 default:
100 return g_strdup(text_from_time(d));
101 break;
102 }
103
104
105 if (format && strftime(buf, sizeof(buf), format, &td) > 0)
106 {
107 gchar *ret = g_locale_to_utf8(buf, -1, NULL, NULL, NULL);
108 if (ret) return ret;
109 }
110
111 return g_strdup("");
112 }
113
114 time_t pan_date_to_time(gint year, gint month, gint day)
115 {
116 struct tm lt;
117
118 lt.tm_sec = 0;
119 lt.tm_min = 0;
120 lt.tm_hour = 0;
121 lt.tm_mday = (day >= 1 && day <= 31) ? day : 1;
122 lt.tm_mon = (month >= 1 && month <= 12) ? month - 1 : 0;
123 lt.tm_year = year - 1900;
124 lt.tm_isdst = 0;
125
126 return mktime(&lt);
127 }
128
129
130 /*
131 *-----------------------------------------------------------------------------
132 * folder validation
133 *-----------------------------------------------------------------------------
134 */
135
136 gint pan_is_link_loop(const gchar *s)
137 {
138 gchar *sl;
139 struct stat st;
140 gint ret = FALSE;
141
142 sl = path_from_utf8(s);
143
144 if (lstat(sl, &st) == 0 && S_ISLNK(st.st_mode))
145 {
146 gchar *buf;
147 gint l;
148
149 buf = g_malloc(st.st_size + 1);
150 l = readlink(sl, buf, st.st_size);
151 if (l == st.st_size)
152 {
153 buf[l] = '\0';
154
155 parse_out_relatives(buf);
156 l = strlen(buf);
157
158 parse_out_relatives(sl);
159
160 if (buf[0] == '/')
161 {
162 if (strncmp(sl, buf, l) == 0 &&
163 (sl[l] == '\0' || sl[l] == '/' || l == 1)) ret = TRUE;
164 }
165 else
166 {
167 gchar *link_path;
168
169 link_path = concat_dir_and_file(sl, buf);
170 parse_out_relatives(link_path);
171
172 if (strncmp(sl, link_path, l) == 0 &&
173 (sl[l] == '\0' || sl[l] == '/' || l == 1)) ret = TRUE;
174
175 g_free(link_path);
176 }
177 }
178
179 g_free(buf);
180 }
181
182 g_free(sl);
183
184 return ret;
185 }
186
187 gint pan_is_ignored(const gchar *s, gint ignore_symlinks)
188 {
189 struct stat st;
190 const gchar *n;
191
192 if (!lstat_utf8(s, &st)) return TRUE;
193
194 #if 0
195 /* normal filesystems have directories with some size or block allocation,
196 * special filesystems (like linux /proc) set both to zero.
197 * enable this check if you enable listing the root "/" folder
198 */
199 if (st.st_size == 0 && st.st_blocks == 0) return TRUE;
200 #endif
201
202 if (S_ISLNK(st.st_mode) && (ignore_symlinks || pan_is_link_loop(s))) return TRUE;
203
204 n = filename_from_path(s);
205 if (n && strcmp(n, GQVIEW_RC_DIR) == 0) return TRUE;
206
207 return FALSE;
208 }
209
210 GList *pan_list_tree(const gchar *path, SortType sort, gint ascend,
211 gint ignore_symlinks)
212 {
213 GList *flist = NULL;
214 GList *dlist = NULL;
215 GList *result;
216 GList *folders;
217
218 filelist_read(path, &flist, &dlist);
219 if (sort != SORT_NONE)
220 {
221 flist = filelist_sort(flist, sort, ascend);
222 dlist = filelist_sort(dlist, sort, ascend);
223 }
224
225 result = flist;
226 folders = dlist;
227 while (folders)
228 {
229 FileData *fd;
230
231 fd = folders->data;
232 folders = g_list_remove(folders, fd);
233
234 if (!pan_is_ignored(fd->path, ignore_symlinks) &&
235 filelist_read(fd->path, &flist, &dlist))
236 {
237 if (sort != SORT_NONE)
238 {
239 flist = filelist_sort(flist, sort, ascend);
240 dlist = filelist_sort(dlist, sort, ascend);
241 }
242
243 result = g_list_concat(result, flist);
244 folders = g_list_concat(dlist, folders);
245 }
246
247 file_data_free(fd);
248 }
249
250 return result;
251 }
252