/* iconlist.c * Copyright (C) 2002-2004 Pascal Eberhard * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "common.h" #include #include #include #include #include #define _GNU_SOURCE 1 #include //#ifndef FNM_CASEFOLD // case insensitive but is not defined... ? //#define FNM_CASEFOLD (1 << 4) //#endif typedef struct scandir_context_t { icon_list_t *icons; } scandir_context_t; static scandir_context_t scandir_context = { .icons = NULL }; static int icon_list_scandir_icon(const struct dirent *de); static int icon_list_scandir_path(const struct dirent *de); // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- icodir_t* icodir_new_child(gchar *dirname, gboolean sel, gboolean rec, icodir_t *parent) { icodir_t *dir; g_assert(dirname != NULL); dir = (icodir_t*) malloc(sizeof(icodir_t)); g_assert(dir != NULL); dir->path = dirname; dir->count_total = 0; dir->count_selected = 0; dir->recursive = rec; dir->selected = sel; dir->parent = parent; dir->children = NULL; if (parent != NULL) parent->children = g_list_append(parent->children, dir); return dir; } // ---------------------------------------------------------------------------- icodir_t* icodir_new(gchar *dirname, gboolean sel, gboolean rec) { return icodir_new_child(dirname, sel, rec, NULL); } // ---------------------------------------------------------------------------- void icodir_free(icodir_t *icodir) { g_assert(icodir != NULL); g_assert(icodir->children == NULL); if (icodir->count_total != 0) ERR("path:%s, count_total:%d", icodir->path, icodir->count_total); if (icodir->path != NULL) g_free(icodir->path); if (icodir->parent != NULL) icodir->parent->children = g_list_remove(icodir->parent->children, icodir); g_free(icodir); } // ---------------------------------------------------------------------------- gint icodir_compare(icodir_t *a, icodir_t *b) { g_assert(a != NULL && b != NULL); if (strcmp("", a->path) == 0) return 1; if (strcmp("", b->path) == 0) return -1; return strcmp(a->path, b->path); } // ---------------------------------------------------------------------------- gint icodir_count_total_rec(icodir_t *dir) { GList *hamster; icodir_t *childdir; gint count; g_assert(dir != NULL); count = dir->count_total; hamster = g_list_first(dir->children); while(hamster) { childdir = hamster->data; count += icodir_count_total_rec(childdir); hamster = g_list_next(hamster); } return count; } // ---------------------------------------------------------------------------- gint icodir_count_selected_rec(icodir_t *dir) { GList *hamster; icodir_t *childdir; gint count; g_assert(dir != NULL); count = dir->count_selected; hamster = g_list_first(dir->children); while(hamster) { childdir = hamster->data; count += icodir_count_selected_rec(childdir); hamster = g_list_next(hamster); } return count; } // ---------------------------------------------------------------------------- icodir_t * icodir_list_find(GList *dirs, char *dirname) { icodir_t *dir; GList *hamster; g_assert(dirname != NULL); TRACE("dirname:%s", dirname); hamster = g_list_first(dirs); while (hamster != NULL) { dir = hamster->data; if (strcmp(dir->path, dirname) == 0) break; hamster = g_list_next(hamster); } if (hamster == NULL) return NULL; return dir; } // ---------------------------------------------------------------------------- GList * icodir_list_find_with_parent(GList *dirs, icodir_t *parentdir) { icodir_t *dir; GList *hamster; g_assert(parentdir != NULL); TRACE("dir:%p", parentdir); hamster = g_list_first(dirs); while (hamster != NULL) { dir = hamster->data; if (dir == parentdir) break; hamster = g_list_next(hamster); } return hamster; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- ico_t* ico_new(icodir_t *dir, gchar *name) { ico_t *ico; char filename[FILENAME_MAX]; g_assert(dir != NULL && name != NULL); g_assert((strlen(dir->path) + strlen(name)) < FILENAME_MAX); ico = (ico_t *) malloc(sizeof(ico_t)); g_assert(ico != NULL); ico->dir = dir; ico->name = name; strcpy(filename, dir->path); strcat(filename, "/"); strcat(filename, ico->name); ico->pixbuf = gdk_pixbuf_new_from_apwal(filename, &ico->width, &ico->height); if (!ico->pixbuf) { TRACE("failed loading pixbuf, return NULL, %s", filename); g_free(name); g_free(ico); return NULL; } ico->selected = FALSE; ico->dir->count_total++; return ico; } // ---------------------------------------------------------------------------- void ico_free(ico_t *ico) { g_assert(ico != NULL); if (ico->name != NULL) g_free(ico->name); if (ico->pixbuf != NULL) g_object_unref(ico->pixbuf); if (ico->dir != NULL) ico->dir->count_total--; g_free(ico); } // ---------------------------------------------------------------------------- gint ico_compare_by_name(ico_t *a, ico_t *b) { g_assert(a != NULL && b != NULL); return strcmp(a->name, b->name); } // ---------------------------------------------------------------------------- gint ico_compare_by_path(ico_t *a, ico_t *b) { gint res; g_assert(a != NULL && b != NULL); g_assert(a->dir != NULL && b->dir != NULL); res = strcmp(a->dir->path, b->dir->path); if (res == 0) res = strcmp(a->name, b->name); return res; } // ---------------------------------------------------------------------------- char *ico_get_full_filename(ico_t *ico) { static char file[FILENAME_MAX]; g_assert(ico != NULL); g_assert(ico->dir != NULL); strcpy(file, ico->dir->path); strcat(file, "/"); strcat(file, ico->name); return file; } // ---------------------------------------------------------------------------- ico_t *ico_list_find_icon(GList *icos, icodir_t *dir, char *ico_name) { GList *hamster; ico_t ico; //icos could be empty (so icos==NULL). g_assert(dir != NULL && ico_name != NULL); //create a fake icon with only the dir and name set for the search ico.dir = dir; ico.name = ico_name; hamster = g_list_find_custom(icos, &ico, (GCompareFunc)ico_compare_by_path); if (hamster == NULL) return NULL; return ((ico_t *)(hamster->data)); } // ---------------------------------------------------------------------------- ico_t *ico_list_try_select_icon(icodir_t *dir, char *ico_name, icon_list_t *icons) { ico_t *ico; GList *ext_hamster; file_ext_t *ext; int cc; gboolean selected; g_assert(dir != NULL && ico_name != NULL && icons != NULL); // check if the name is matching one of the patterns // if name matches pattern then go out the loop with cc=0 // if name don't match any pattern then cc!=0 at the end of the loop // so after the loop, if cc!=0 then don't select the name ext_hamster = g_list_first(icons->iconsel->apwal->iconsel_pref->file_exts); selected = FALSE; while(ext_hamster != NULL && selected == FALSE) { ext = ext_hamster->data; if (ext->selected == TRUE) { cc = fnmatch(ext->extension, ico_name, FNM_CASEFOLD); //TRACE("ext:%s, name:%s, cc:%d", ext->extension, ico_name, cc); if (cc == 0) // success { selected = TRUE; break; } if ((cc != 0) && (cc != FNM_NOMATCH)) // error during match WARN("fnmatch, ext:%s, name:%s, E:%d", ext->extension, ico_name, cc); } ext_hamster = g_list_next(ext_hamster); } //end while ext if (selected == FALSE) // not match return NULL; // the next tests need the icon to be created. create the icon now ico = ico_new(dir, g_strdup(ico_name)); if (ico == NULL) return NULL; // check if the size of the icon match the selected size selected = FALSE; if ((icons->iconsel->apwal->iconsel_pref->select_48 == TRUE) && (ico->width == 48) && (ico->height == 48)) selected = TRUE; else if ((icons->iconsel->apwal->iconsel_pref->select_gt48 == TRUE) && ((ico->width > 48) || (ico->height > 48))) selected = TRUE; else if ((icons->iconsel->apwal->iconsel_pref->select_lt48 == TRUE) && ((ico->width < 48) || (ico->height < 48))) selected = TRUE; if (selected == FALSE) { ico_free(ico); return NULL; } return ico; } // ---------------------------------------------------------------------------- void ico_list_append(GList **icos, icodir_t *dir, icon_list_t *icons) { struct dirent **namelist; int n; ico_t *ico; ico_t *found; g_assert(icos != NULL && dir != NULL && icons != NULL); n = scandir(dir->path, &namelist, icon_list_scandir_icon, alphasort); if (n < 0) { TRACE("scandir dir:%s, cc:%d, E:%d", dir->path, n, errno); return; } while(n--) { //TRACE("*icos:%p, dir:%p, namelist[n]->d_name:%p", // *icos, dir, namelist[n]->d_name); ico = ico_list_try_select_icon(dir, namelist[n]->d_name, icons); found = ico_list_find_icon(*icos, dir, namelist[n]->d_name); if (ico != NULL && found == NULL) *icos = g_list_append(*icos, ico); else if (ico != NULL && found != NULL) ico_free(ico); else if (ico == NULL && found != NULL) { *icos = g_list_remove(*icos, found); if (found == icon_list_get_selected_icon(icons)) icon_list_set_selected_icon(icons, NULL); ico_free(found); } free(namelist[n]); } free(namelist); TRACE("path:%s, count_total:%d", dir->path, dir->count_total); } // ---------------------------------------------------------------------------- void ico_list_remove(GList **icos, icodir_t *dir, icon_list_t *icons) { GList *hamster; ico_t *ico; gint i, count, dircount, dircount2; g_assert(icos != NULL && dir != NULL && icons != NULL); i = 0; dircount = dir->count_total; dircount2 = 0; hamster = g_list_first(*icos); while(hamster) { ico = hamster->data; if (ico->dir == dir) dircount2++; hamster = g_list_next(hamster); } count = g_list_length(*icos); hamster = g_list_first(*icos); while (hamster != NULL) { ico = hamster->data; if (ico->dir == dir) { if (hamster == g_list_first(*icos)) { *icos = g_list_remove(*icos, ico); if (ico == icon_list_get_selected_icon(icons)) icon_list_set_selected_icon(icons, NULL); hamster = g_list_first(*icos); } else { hamster = g_list_remove(hamster, ico); if (ico == icon_list_get_selected_icon(icons)) icon_list_set_selected_icon(icons, NULL); } i++; ico_free(ico); } else hamster = g_list_next(hamster); } if (dircount != i) ERR("icon list:%d, path:%s, dir->count_total:%d != i:%d", count, dir->path, dircount, i); TRACE("icon list:%d, path:%s, dir->count_total:%d, dircount2:%d, i:%d", count, dir->path, dircount, dircount2, i); } // ---------------------------------------------------------------------------- void ico_list_sort(GList **icos, gint sortmode) { g_assert(icos != NULL); switch(sortmode) { case ICONSEL_SORT_NAME: *icos = g_list_sort(*icos, (GCompareFunc)ico_compare_by_name); break; case ICONSEL_SORT_PATH: *icos = g_list_sort(*icos, (GCompareFunc)ico_compare_by_path); break; default: ERR("sortmode:%d invalid", sortmode); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- icon_list_t * icon_list_new(icon_selection_t *iconsel) { icon_list_t *icons; TRACE("%s", ""); g_assert(iconsel != NULL); icons = (icon_list_t *) malloc(sizeof(icon_list_t)); g_assert(icons != NULL); icons->iconsel = iconsel; icons->dirs = NULL; icons->icos = NULL; icons->sortmode = ICONSEL_SORT_NAME; icons->pixbuf = NULL; icons->selected_icon = NULL; icons->icon_per_row = 10; scandir_context.icons = icons; return icons; } // ---------------------------------------------------------------------------- void icon_list_free(icon_list_t *icons) { GList *hamster; icodir_t *dir; ico_t *ico; g_assert(icons != NULL); TRACE("%s", ""); // free icon list hamster = g_list_first(icons->icos); while (hamster != NULL) { ico = hamster->data; ico_free(ico); hamster = g_list_next(hamster); } g_list_free(icons->icos); // free dir list hamster = g_list_first(icons->dirs); while (hamster != NULL) { dir = hamster->data; icodir_free(dir); hamster = g_list_next(hamster); } g_list_free(icons->dirs); if (icons->pixbuf) g_object_unref(icons->pixbuf); g_free(icons); } // ---------------------------------------------------------------------------- void icon_list_set_width(icon_list_t *icons, int icon_per_row) { g_assert((icons != NULL) || (icon_per_row <= 0)); icons->icon_per_row = icon_per_row; } // ---------------------------------------------------------------------------- void icon_list_append_children(icon_list_t *icons, icodir_t *dir) { struct dirent **namelist; char dirname[FILENAME_MAX]; int n; icodir_t *childdir; g_assert(icons != NULL && dir != NULL); g_assert(dir->recursive == TRUE); TRACE("'%s'", dir->path); splash_update(icons->iconsel->apwal->splash); n = scandir(dir->path, &namelist, icon_list_scandir_path, alphasort); if (n < 0) { WARN("scandir:%d, errno:%d", n, errno); return; } while(n--) { // buid the abolute path of the child directory strcpy(dirname, dir->path); strcat(dirname, "/"); strcat(dirname, namelist[n]->d_name); // check if the child directory already exist // if the child do not already exist then create it and follow the child, // if the child already exist then do nothing end of the branch here. childdir = icodir_list_find(icons->dirs, dirname); if (childdir == NULL) { childdir = icodir_new_child(g_strdup(dirname), dir->selected, dir->recursive, dir); icons->dirs = g_list_insert_sorted(icons->dirs, childdir, (GCompareFunc) icodir_compare); ico_list_append(&icons->icos, childdir, icons); icon_list_append_children(icons, childdir); } else { if (childdir->parent == dir) { TRACE("'%s' exist and it is our child, reload it", dirname); ico_list_append(&icons->icos, childdir, icons); icon_list_append_children(icons, childdir); } else TRACE("'%s' exist and we are not his parent, stop this branch here", dirname); } free(namelist[n]); }// end while n-- free(namelist); } // ---------------------------------------------------------------------------- void icon_list_append(icon_list_t *icons, char *dirname, gboolean selected, gboolean recursive) { icodir_t *dir; g_assert(icons != NULL && dirname != NULL); TRACE("'%s' selected:%d recursive:%d", dirname, selected, recursive); splash_update(icons->iconsel->apwal->splash); dir = icodir_list_find(icons->dirs, dirname); if (dir != NULL) { if (dir->parent != NULL) icon_list_fork(icons, dir, selected, recursive); else ERR("dirname:%s already exist", dirname); } else { dir = icodir_new(g_strdup(dirname), selected, recursive); icons->dirs = g_list_insert_sorted(icons->dirs, dir, (GCompareFunc) icodir_compare); ico_list_append(&icons->icos, dir, icons); if (dir->recursive == TRUE) icon_list_append_children(icons, dir); } ico_list_sort(&icons->icos, icons->sortmode); } // ---------------------------------------------------------------------------- void icon_list_reload(icon_list_t *icons, char *dirname) { icodir_t *dir; g_assert(icons != NULL && dirname != NULL); TRACE("reload '%s'", dirname); dir = icodir_list_find(icons->dirs, dirname); if (dir == NULL) ERR("dirname:%s not found", dirname); if (dir->parent != NULL) ERR("dirname:%s is not a root of a dir tree", dirname); ico_list_append(&icons->icos, dir, icons); if (dir->recursive == TRUE) icon_list_append_children(icons, dir); ico_list_sort(&icons->icos, icons->sortmode); } // ---------------------------------------------------------------------------- void icon_list_reload_all_with_splash(icon_list_t *icons) { g_assert(icons != NULL); splash_show(icons->iconsel->apwal->splash); icon_list_reload_all(icons); splash_hide(icons->iconsel->apwal->splash); } // ---------------------------------------------------------------------------- void icon_list_reload_all(icon_list_t *icons) { GList *hamster; icon_dir_t *icon_dir; g_assert(icons != NULL); // use a little trick here. As the dir list is suspectible to change during // the loop, use the list of dirs owned by iconsel for the loop (which will // not change). hamster = g_list_first(icons->iconsel->apwal->iconsel_pref->icon_dirs); while (hamster != NULL) { icon_dir = (icon_dir_t*) hamster->data; icon_list_reload(icons, icon_dir->path); hamster = g_list_next(hamster); } } // ---------------------------------------------------------------------------- void icon_list_remove_children(icon_list_t *icons, icodir_t *dir) { GList *hamster; icodir_t *childdir; g_assert(icons != NULL && dir != NULL); g_assert(dir->recursive == TRUE); if (dir->children == NULL) return; TRACE("%s", dir->path); //hamster = icodir_list_find_with_parent(dir->children, dir); hamster = g_list_first(dir->children); while (hamster != NULL) { childdir = hamster->data; TRACE("parent:%p, childdir:%p", dir, childdir); icon_list_remove_children(icons, childdir); ico_list_remove(&icons->icos, childdir, icons); icons->dirs = g_list_remove(icons->dirs, childdir); hamster = g_list_next(hamster); icodir_free(childdir); //hamster = icodir_list_find_with_parent(dir->children, dir); } g_list_free(dir->children); dir->children = NULL; } // ---------------------------------------------------------------------------- void icon_list_remove(icon_list_t *icons, char *dirname) { icodir_t *dir; g_assert(icons != NULL && dirname != NULL); TRACE("'%s'", dirname); dir = icodir_list_find(icons->dirs, dirname); if (dir == NULL) ERR("dirname:%s not exist", dirname); if (dir->recursive == TRUE) icon_list_remove_children(icons, dir); ico_list_remove(&icons->icos, dir, icons); icons->dirs = g_list_remove(icons->dirs, dir); icodir_free(dir); } // ---------------------------------------------------------------------------- void icon_list_modify_with_splash(icon_list_t *icons, char *dirname, char *newdirname) { g_assert(icons != NULL); splash_show(icons->iconsel->apwal->splash); icon_list_modify(icons, dirname, newdirname); splash_hide(icons->iconsel->apwal->splash); } // ---------------------------------------------------------------------------- void icon_list_modify(icon_list_t *icons, char *dirname, char *newdirname) { icodir_t *dir; gboolean selected, recursive; g_assert(icons != NULL && dirname != NULL && newdirname != NULL); TRACE("old:'%s', new:'%s'", dirname, newdirname); dir = icodir_list_find(icons->dirs, dirname); if (dir == NULL) ERR("dirname:%s not exist, newdirname:%s", dirname, newdirname); recursive = dir->recursive; selected = dir->selected; icon_list_remove(icons, dirname); icon_list_append(icons, newdirname, selected, recursive); } // ---------------------------------------------------------------------------- void icon_list_fork(icon_list_t *icons, icodir_t *dir, gboolean selected, gboolean recursive) { gint len1, len2; g_assert(icons != NULL && dir != NULL); g_assert(dir->parent != NULL); TRACE("'%s'", dir->path); // remove link with parent. you are now a grown up people my child... len1 = g_list_length(dir->parent->children); dir->parent->children = g_list_remove(dir->parent->children, dir); len2 = g_list_length(dir->parent->children); if (len2 != len1 - 1) ERR("remove from dir->parent->children, dir:%s, parent:%s, " "len1:%d len2:%d", dir->path, dir->parent->path, len1, len2); dir->parent = NULL; // set recursive and selected properties if (dir->recursive != recursive) icon_list_set_recursive(icons, dir->path, recursive); if (dir->selected != selected) icon_list_set_selected(icons, dir->path, selected); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- void icon_list_set_selected_children(icon_list_t *icons, icodir_t *dir, gboolean selected) { GList *hamster; icodir_t *childdir; g_assert(icons != NULL && dir != NULL); TRACE("dir->selected:%d, selected:%d", dir->selected, selected); hamster = g_list_first(dir->children); while (hamster) { childdir = hamster->data; childdir->selected = selected; icon_list_set_selected_children(icons, childdir, selected); hamster = g_list_next(hamster); } } // ---------------------------------------------------------------------------- void icon_list_set_selected(icon_list_t *icons, char *dirname, gboolean selected) { icodir_t *dir; g_assert(icons != NULL && dirname != NULL); TRACE("%s", ""); dir = icodir_list_find(icons->dirs, dirname); if (dir == NULL) ERR("dirname:%s not exist", dirname); if (dir->selected == selected) ERR("dirname:%s, dir->selected:%d == selected:%d", dirname, dir->selected, selected); dir->selected = selected; if (dir->recursive == TRUE) icon_list_set_selected_children(icons, dir, selected); } // ---------------------------------------------------------------------------- void icon_list_set_recursive_with_splash(icon_list_t *icons, char *dirname, gboolean recursive) { g_assert(icons != NULL); splash_show(icons->iconsel->apwal->splash); icon_list_set_recursive(icons, dirname, recursive); splash_hide(icons->iconsel->apwal->splash); } // ---------------------------------------------------------------------------- void icon_list_set_recursive(icon_list_t *icons, char *dirname, gboolean recursive) { icodir_t *dir; g_assert(icons != NULL && dirname != NULL); dir = icodir_list_find(icons->dirs, dirname); if (dir == NULL) ERR("dirname:%s not exist", dirname); if (dir->recursive == recursive) ERR("dirname:%s, dir->recursive:%d == recursive:%d", dirname, dir->recursive, recursive); if (recursive == TRUE) { dir->recursive = recursive; icon_list_append_children(icons, dir); } else { icon_list_remove_children(icons, dir); dir->recursive = recursive; } } // ---------------------------------------------------------------------------- void icon_list_select (icon_list_t *icons, gboolean (*select_func)(ico_t *ico, void *data), void *data) { GList *hamster; ico_t *ico; icodir_t *dir; g_assert(icons != NULL && select_func != NULL); hamster = g_list_first(icons->dirs); while (hamster != NULL) { dir = hamster->data; dir->count_selected = 0; hamster = g_list_next(hamster); } hamster = g_list_first(icons->icos); while (hamster != NULL) { ico = hamster->data; if (ico->dir->selected == FALSE) ico->selected = FALSE; else ico->selected = select_func(ico, data); if (ico->selected == TRUE) ico->dir->count_selected++; hamster = g_list_next(hamster); } } // ---------------------------------------------------------------------------- ico_t *icon_list_find(icon_list_t *icons, char *path, char *name) { GList *hamster; ico_t *ico; icodir_t *dir; g_assert(icons != NULL && path != NULL && name != NULL); dir = icodir_list_find(icons->dirs, path); if (dir == NULL) return NULL; hamster = g_list_first(icons->icos); while (hamster != NULL) { ico = hamster->data; if (ico->dir == dir) if (strcmp(ico->name, name) == 0) break; hamster = g_list_next(hamster); } if (hamster == NULL) return NULL; return ico; } // ---------------------------------------------------------------------------- icodir_t *icon_list_find_path(icon_list_t *icons, char *path) { g_assert(icons != NULL && path != NULL); return icodir_list_find(icons->dirs, path); } // ---------------------------------------------------------------------------- void icon_list_set_sortmode(icon_list_t *icons, int sortmode) { g_assert(icons != NULL); icons->sortmode = sortmode; ico_list_sort(&icons->icos, icons->sortmode); } // ---------------------------------------------------------------------------- gint icon_list_selected_count(icon_list_t *icons) { ico_t *ico; GList *hamster; int count; g_assert(icons != NULL); count = 0; hamster = g_list_first(icons->icos); while (hamster != NULL) { ico = hamster->data; if (ico->selected) count++; hamster = g_list_next(hamster); } return count; } // ---------------------------------------------------------------------------- ico_t *icon_list_selected_nth(icon_list_t *icons, int nth) { ico_t *ico; GList *hamster; int i; g_assert(icons != NULL); i = 0; hamster = g_list_first(icons->icos); while (hamster != NULL && i != nth) { ico = hamster->data; if (ico->selected == TRUE) i++; hamster = g_list_next(hamster); } if (hamster == NULL) return NULL; return ico; } // ---------------------------------------------------------------------------- GdkPixbuf *icon_list_pixbuf(icon_list_t *icons) { GList *hamster; gint i, count; gint width; gint height; ico_t *ico; gint index_of_selected; g_assert(icons != NULL); count = icon_list_selected_count(icons); width = icons->icon_per_row * 48; height = ((count / icons->icon_per_row) + 1) * 48; if (icons->pixbuf != NULL) { if ( ! (gdk_pixbuf_get_width(icons->pixbuf) == width && gdk_pixbuf_get_height(icons->pixbuf) == height)) { g_object_unref(icons->pixbuf); icons->pixbuf = NULL; } } if (icons->pixbuf == NULL) icons->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB/*colorspace*/, TRUE/*has_alpha*/, 8/*bits_per_sample*/, width, height); gdk_pixbuf_fill(icons->pixbuf, 0x00000000); i = 0; index_of_selected = -1; hamster = g_list_first(icons->icos); while (hamster) { ico = hamster->data; if (ico->selected == TRUE) { // be carful here, width and height are use but for icon pixbuf now width = gdk_pixbuf_get_width(ico->pixbuf); height = gdk_pixbuf_get_height(ico->pixbuf); width = width < 48 ? width : 48; height= height< 48 ? height: 48; gdk_pixbuf_copy_area(ico->pixbuf/*src_pixbuf*/, 0/*src_x*/, 0/*src_y*/, width, height, icons->pixbuf, (i % icons->icon_per_row) * 48/*x*/, (i / icons->icon_per_row) * 48/*y*/); if (icons->selected_icon == ico) index_of_selected = i; i++; } hamster = g_list_next(hamster); } // end while hamster if (i != count) ERR("i:%d, count:%d", i, count); TRACE("i:%d, count:%d", i, count); return icons->pixbuf; } // ---------------------------------------------------------------------------- void icon_list_set_selected_icon_from_xy(icon_list_t *icons, int x, int y) { int nth; g_assert(icons != NULL); nth = (y * icons->icon_per_row) + x + 1/*first nth is 1 and not 0*/; icons->selected_icon = icon_list_selected_nth(icons, nth); if (icons->selected_icon == NULL) TRACE("%s", "no icon selected"); else TRACE("name:%s", icons->selected_icon->name); } // ---------------------------------------------------------------------------- void icon_list_set_selected_icon_from_filename(icon_list_t *icons, const char *file) { char *dirname, *iconame; g_assert(icons != NULL); if (file == NULL) icons->selected_icon = NULL; else { dirname = g_path_get_dirname(file); iconame = g_path_get_basename(file); icons->selected_icon = icon_list_find(icons, dirname, iconame); g_free(dirname); g_free(iconame); } if (icons->selected_icon == NULL) TRACE("NULL selected, filename:%s not found", file); else TRACE("name:%s", icons->selected_icon->name); } // ---------------------------------------------------------------------------- void icon_list_set_selected_icon(icon_list_t *icons, ico_t *ico) { g_assert(icons != NULL); icons->selected_icon = ico; } // ---------------------------------------------------------------------------- ico_t *icon_list_get_selected_icon(icon_list_t *icons) { g_assert(icons != NULL); return icons->selected_icon; } // ---------------------------------------------------------------------------- gchar *icon_list_get_selected_icon_filename(icon_list_t *icons) { gchar *filename; g_assert(icons != NULL); if (icons->selected_icon == NULL) { TRACE("%s", "icon_list_get_selected_icon_filename() no icon selected"); return NULL; } filename = ico_get_full_filename(icons->selected_icon); TRACE("icon_list_get_selected_icon_filename() file:%s", filename); return filename; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // = 0 : not selected // != 0 : selected, sorted and allocated in namelist by scandir // do many check, if the check failed then return 0, else go to the next check. // arrive at the end, return 1 because the file success all the tests. static int icon_list_scandir_icon(const struct dirent *de) { //icon_list_t *icons = scandir_context.icons; g_assert(de != NULL); // do not select . and .. directories if ((!strcmp(".", de->d_name)) || (!strcmp("..", de->d_name))) { //TRACE("ico_select() 1 de->d_name:%s", de->d_name); return 0; } // if file is a directory, then don't select it if (de->d_type == DT_DIR) { //TRACE("ico_select() 2 de->d_name:%s", de->d_name); return 0; } // if not return before here, then the filename is ok. return 1. return 1; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // = 0 : not selected // != 0 : selected, sorted and allocated in namelist by scandir static int icon_list_scandir_path(const struct dirent *de) { g_assert(de != NULL); // not select . & .. if ((!strcmp(".", de->d_name)) || (!strcmp("..", de->d_name))) { return 0; } // select directories only if (de->d_type != DT_DIR) { return 0; } //de->d_type; //de->d_name; return 1; } // ---------------------------------------------------------------------------- void icon_list_print_not_selected(icon_list_t *icons) //debug stuff { GList *hamster; ico_t *ico; hamster = icons->icos; while (hamster != NULL) { ico = hamster->data; if (ico->selected == FALSE) TRACE("!selected: %dx%d, name:%s, dir:%s", ico->width, ico->height, ico->name, ico->dir->path); hamster = g_list_next(hamster); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------