1 /* iconsel.c
2 * Copyright (C) 2002-2004 Pascal Eberhard <pascal.ebo@netcourrier.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20
21 #include "common.h"
22 #include <dirent.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "iconsel_private.h"
27
28 #define _GNU_SOURCE 1
29 #include <fnmatch.h>
30
31 //#ifndef FNM_CASEFOLD // case insensitive but is not defined... ?
32 //#define FNM_CASEFOLD (1 << 4)
33 //#endif
34
35 // ----------------------------------------------------------------------------
icon_dir_new(gchar * path,gboolean selected,gboolean recursive)36 icon_dir_t *icon_dir_new(gchar *path, gboolean selected, gboolean recursive)
37 {
38 icon_dir_t *icon_dir;
39 g_assert(path != NULL);
40 icon_dir = (icon_dir_t *) malloc(sizeof(icon_dir_t));
41 g_assert(icon_dir != NULL);
42 icon_dir->path = path;
43 icon_dir->selected = selected;
44 icon_dir->recursive = recursive;
45 return icon_dir;
46 }
47 // ----------------------------------------------------------------------------
icon_dir_free(icon_dir_t * icon_dir)48 void icon_dir_free(icon_dir_t *icon_dir)
49 {
50 g_assert(icon_dir != NULL);
51 if (icon_dir->path)
52 g_free(icon_dir->path);
53 g_free(icon_dir);
54 }
55 // ----------------------------------------------------------------------------
icon_dir_compare(icon_dir_t * a,icon_dir_t * b)56 gint icon_dir_compare(icon_dir_t *a, icon_dir_t *b)
57 {
58 g_assert(a != NULL && b != NULL);
59 return strcmp(a->path, b->path);
60 }
61 // ----------------------------------------------------------------------------
icon_dir_list_append(GList ** list,icon_dir_t * dir)62 void icon_dir_list_append(GList **list, icon_dir_t *dir)
63 {
64 g_assert(list != NULL && dir != NULL);
65 *list = g_list_insert_sorted(*list, dir, (GCompareFunc) icon_dir_compare);
66 }
67 // ----------------------------------------------------------------------------
icon_dir_list_find(GList * list,char * olddir)68 icon_dir_t * icon_dir_list_find(GList *list, char *olddir)
69 {
70 GList *hamster;
71 icon_dir_t *dir;
72 g_assert(olddir != NULL);
73 hamster = g_list_first(list);
74 while(hamster != NULL)
75 {
76 dir = hamster->data;
77 if (strcmp(dir->path, olddir) == 0)
78 break;
79 hamster = g_list_next(hamster);
80 }
81 if (hamster == NULL)
82 return NULL;
83 else
84 return dir;
85 }
86 // ----------------------------------------------------------------------------
icon_dir_list_remove(GList ** list,char * olddir)87 void icon_dir_list_remove(GList **list, char *olddir)
88 {
89 GList *hamster;
90 icon_dir_t *dir;
91 g_assert(list != NULL && olddir != NULL);
92 hamster = g_list_first(*list);
93 while(hamster != NULL)
94 {
95 dir = hamster->data;
96 if (strcmp(dir->path, olddir) == 0)
97 break;
98 hamster = g_list_next(hamster);
99 }
100 if (hamster == NULL)
101 ERR("icon_dir_list_remove() olddir:%s not found", olddir);
102
103 *list = g_list_remove(*list, dir);
104 icon_dir_free(dir);
105 }
106 // ----------------------------------------------------------------------------
icon_dir_list_modify(GList ** list,char * olddir,char * newdir)107 void icon_dir_list_modify(GList **list, char *olddir, char *newdir)
108 {
109 GList *hamster;
110 icon_dir_t *dir;
111 g_assert(list != NULL && olddir != NULL && newdir != NULL);
112 hamster = g_list_first(*list);
113 while(hamster != NULL)
114 {
115 dir = hamster->data;
116 if (strcmp(dir->path, newdir) == 0)
117 break;
118 hamster = g_list_next(hamster);
119 }
120 if (hamster != NULL)
121 {
122 WARN("icon_dir_list_modify() olddir:%s, newdir:%s, "
123 "newdir already exist", olddir, newdir);
124 return;
125 }
126
127 hamster = g_list_first(*list);
128 while(hamster != NULL)
129 {
130 dir = hamster->data;
131 if (strcmp(dir->path, olddir) == 0)
132 break;
133 hamster = g_list_next(hamster);
134 }
135 if (hamster == NULL)
136 ERR("icon_dir_list_modify() olddir:%s not found", olddir);
137 g_free(dir->path);
138 dir->path = g_strdup(newdir);
139 *list = g_list_sort(*list, (GCompareFunc) icon_dir_compare);
140 }
141 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
143 // ----------------------------------------------------------------------------
144 // ----------------------------------------------------------------------------
file_ext_new(gchar * extension,gboolean selected)145 file_ext_t *file_ext_new(gchar *extension, gboolean selected)
146 {
147 file_ext_t *file_ext;
148 g_assert(extension != NULL);
149 file_ext = (file_ext_t *) malloc(sizeof(file_ext_t));
150 g_assert(file_ext != NULL);
151 file_ext->extension = extension;
152 file_ext->selected = selected;
153 return file_ext;
154 }
155 // ----------------------------------------------------------------------------
file_ext_free(file_ext_t * file_ext)156 void file_ext_free(file_ext_t *file_ext)
157 {
158 if (file_ext->extension)
159 g_free(file_ext->extension);
160 g_free(file_ext);
161 }
162 // ----------------------------------------------------------------------------
file_ext_compare(file_ext_t * a,file_ext_t * b)163 gint file_ext_compare(file_ext_t *a, file_ext_t *b)
164 {
165 g_assert(a != NULL && b != NULL);
166 return strcmp(a->extension, b->extension);
167 }
168 // ----------------------------------------------------------------------------
file_ext_list_append(GList ** list,file_ext_t * ext)169 void file_ext_list_append(GList **list, file_ext_t *ext)
170 {
171 g_assert(list != NULL && ext != NULL);
172 *list = g_list_insert_sorted(*list, ext, (GCompareFunc) file_ext_compare);
173 }
174 // ----------------------------------------------------------------------------
file_ext_list_find(GList * list,char * oldext)175 file_ext_t * file_ext_list_find(GList *list, char *oldext)
176 {
177 GList *hamster;
178 file_ext_t *ext;
179 g_assert(oldext != NULL);
180 hamster = g_list_first(list);
181 while(hamster != NULL)
182 {
183 ext = hamster->data;
184 if (strcmp(ext->extension, oldext) == 0)
185 break;
186 hamster = g_list_next(hamster);
187 }
188 if (hamster == NULL)
189 return NULL;
190 else
191 return ext;
192 }
193 // ----------------------------------------------------------------------------
file_ext_list_remove(GList ** list,char * oldext)194 void file_ext_list_remove(GList **list, char *oldext)
195 {
196 GList *hamster;
197 file_ext_t *ext;
198 g_assert(list != NULL && oldext != NULL);
199 hamster = g_list_first(*list);
200 while(hamster != NULL)
201 {
202 ext = hamster->data;
203 if (strcmp(ext->extension, oldext) == 0)
204 break;
205 hamster = g_list_next(hamster);
206 }
207 if (hamster == NULL)
208 ERR("file_ext_list_remove() oldext:%s not found", oldext);
209
210 *list = g_list_remove(*list, ext);
211 file_ext_free(ext);
212 }
213 // ----------------------------------------------------------------------------
file_ext_list_modify(GList ** list,char * oldext,char * newext)214 void file_ext_list_modify(GList **list, char *oldext, char *newext)
215 {
216 GList *hamster;
217 file_ext_t *ext;
218 g_assert(list != NULL && oldext != NULL && newext != NULL);
219 hamster = g_list_first(*list);
220 while(hamster != NULL)
221 {
222 ext = hamster->data;
223 if (strcmp(ext->extension, newext) == 0)
224 break;
225 hamster = g_list_next(hamster);
226 }
227 if (hamster != NULL)
228 {
229 WARN("file_ext_list_modify() oldext:%s, newext:%s, "
230 "newext already exist", oldext, newext);
231 return;
232 }
233 hamster = g_list_first(*list);
234 while(hamster != NULL)
235 {
236 ext = hamster->data;
237 if (strcmp(ext->extension, oldext) == 0)
238 break;
239 hamster = g_list_next(hamster);
240 }
241 if (hamster == NULL)
242 ERR("file_ext_list_modify() oldext:%s not found", oldext);
243 g_free(ext->extension);
244 ext->extension = g_strdup(newext);
245 *list = g_list_sort(*list, (GCompareFunc) file_ext_compare);
246 }
247 // ----------------------------------------------------------------------------
248 // ----------------------------------------------------------------------------
249 // ----------------------------------------------------------------------------
250 // ----------------------------------------------------------------------------
251 // ----------------------------------------------------------------------------
iconsel_pref_new(GList * icon_dirs,GList * file_exts,gboolean eq48,gboolean lt48,gboolean gt48,gint sort)252 iconsel_pref_t * iconsel_pref_new(GList *icon_dirs, GList *file_exts,
253 gboolean eq48, gboolean lt48,
254 gboolean gt48, gint sort)
255 {
256 iconsel_pref_t *ispref;
257 TRACE("%s", "");
258 ispref = (iconsel_pref_t *) malloc(sizeof(iconsel_pref_t));
259 g_assert(ispref != NULL);
260 ispref->icon_dirs = icon_dirs;
261 ispref->file_exts = file_exts;
262 ispref->select_48 = eq48;
263 ispref->select_lt48 = lt48;
264 ispref->select_gt48 = gt48;
265 if (sort < 0 || sort > ICONSEL_SORT_LAST)
266 {
267 WARN("sort_mode:%d invalid, set to default:%d",
268 sort, ICONSEL_SORT_DEFAULT);
269 sort = ICONSEL_SORT_DEFAULT;
270 }
271 ispref->sort_mode = sort;
272 return ispref;
273 }
274 // ----------------------------------------------------------------------------
275 // ----------------------------------------------------------------------------
276 // ----------------------------------------------------------------------------
277 // ----------------------------------------------------------------------------
278 // ----------------------------------------------------------------------------
279 // ----------------------------------------------------------------------------
280 // ----------------------------------------------------------------------------
281 // ----------------------------------------------------------------------------
icon_selection_new(struct apwalapp_t * apwal)282 icon_selection_t* icon_selection_new(struct apwalapp_t *apwal)
283 {
284 icon_selection_t *iconsel;
285
286 g_assert(apwal != NULL);
287 TRACE("%s", "");
288
289 iconsel = (icon_selection_t *) malloc(sizeof(icon_selection_t));
290 g_assert(iconsel != NULL);
291
292 iconsel->apwal = apwal;
293 iconsel->filter = g_strdup("*");
294
295 iconsel->image = NULL;
296
297 iconsel->dblclick_timer = NULL;
298 iconsel->dblclick_selected_timer = NULL;
299
300 iconsel->never_refreshed = TRUE;
301
302 iconsel->icons = icon_list_new(iconsel);
303 iconsel_build_interface(iconsel);
304 return iconsel;
305 }
306
307 // ----------------------------------------------------------------------------
icon_selection_load_icons_with_splash(icon_selection_t * iconsel)308 void icon_selection_load_icons_with_splash(icon_selection_t *iconsel)
309 {
310 GList *hamster;
311 icon_dir_t *icon_dir;
312 g_assert(iconsel != NULL);
313 splash_show(iconsel->apwal->splash);
314 hamster = iconsel->apwal->iconsel_pref->icon_dirs;
315 while(hamster != NULL)
316 {
317 splash_update(iconsel->apwal->splash);
318 icon_dir = hamster->data;
319 icon_list_append(iconsel->icons, icon_dir->path,
320 icon_dir->selected, icon_dir->recursive);
321 hamster = g_list_next(hamster);
322 }
323 splash_hide(iconsel->apwal->splash);
324 iconsel_path_refresh(iconsel);
325 }
326 // ----------------------------------------------------------------------------
327 // ----------------------------------------------------------------------------
328 // usage: icon_list_select(iconsel->icons, iconsel_select_func, iconsel);
iconsel_select_func(ico_t * ico,void * data)329 gboolean iconsel_select_func(ico_t *ico, void *data)
330 {
331 gboolean selected;
332 int cc;
333 icon_selection_t *iconsel = (icon_selection_t *) data;
334 g_assert(ico != NULL && iconsel != NULL);
335
336 selected = TRUE;
337 while (1) // begin of a 'block' which can be aborted by a break
338 {
339 #if 0
340 GList *ext_hamster;
341 file_ext_t *ext;
342 // check if the size is selected
343 if ((iconsel->ispref->select_48 == TRUE) &&
344 (ico->width == 48) && (ico->height == 48))
345 selected = TRUE;
346 else if ((iconsel->ispref->select_gt48 == TRUE) &&
347 ((ico->width > 48) || (ico->height > 48)))
348 selected = TRUE;
349 else if ((iconsel->ispref->select_lt48 == TRUE) &&
350 ((ico->width < 48) || (ico->height < 48)))
351 selected = TRUE;
352 else
353 {
354 selected = FALSE;
355 break;
356 }
357
358 // check if the name is matching one of the patterns
359 // if name matches pattern then go out the loop with cc=0
360 // if name don't match any pattern then cc!=0 at the end of the loop
361 // after the loop, if cc!=0 then don't select the name and return 0
362 ext_hamster = g_list_first(iconsel->ispref->file_exts);
363 while(ext_hamster != NULL)
364 {
365 ext = ext_hamster->data;
366 if (ext->selected == TRUE)
367 {
368 cc = fnmatch(ext->extension, ico->name, FNM_CASEFOLD);
369 //TRACE("ext:%s, name:%s, cc:%d", ext->extension, ico->name, cc);
370 if (cc == 0) // success
371 break;
372
373 if ((cc != 0) && (cc != FNM_NOMATCH)) // error during match
374 WARN("fnmatch, ext:%s, name:%s, E:%d",
375 ext->extension, ico->name, cc);
376 }
377 ext_hamster = g_list_next(ext_hamster);
378 } //end while ext
379 if (cc != 0 || ext_hamster == NULL) // not match
380 {
381 selected = FALSE;
382 break;
383 }
384 #endif
385
386 // check if the name match the filter
387 cc = fnmatch(iconsel->filter, ico->name, FNM_CASEFOLD);
388 if (cc != 0)
389 {
390 selected = FALSE;
391 if (cc != FNM_NOMATCH)
392 WARN("fnmatch filter:%s, name:%s, E:%d",
393 iconsel->filter, ico->name, cc);
394 break;
395 }
396 break; // end of the 'block'
397 } // end of the 'block'
398 return selected;
399 }
400 // ----------------------------------------------------------------------------
401 // ----------------------------------------------------------------------------
iconsel_set_filename(icon_selection_t * iconsel,const char * filename)402 void iconsel_set_filename(icon_selection_t *iconsel, const char *filename)
403 {
404 g_assert(iconsel != NULL);
405 TRACE("%s", "");
406 icon_list_set_selected_icon_from_filename(iconsel->icons, filename);
407 }
408 // ----------------------------------------------------------------------------
409 // ----------------------------------------------------------------------------
iconsel_get_filename(icon_selection_t * iconsel)410 char *iconsel_get_filename(icon_selection_t *iconsel)
411 {
412 g_assert(iconsel != NULL);
413 TRACE("%s", "");
414 return icon_list_get_selected_icon_filename(iconsel->icons);
415 }
416 // ----------------------------------------------------------------------------
417 // ----------------------------------------------------------------------------
418 // ----------------------------------------------------------------------------
419 // ----------------------------------------------------------------------------
420