/* * Copyright (C) 2002 Edscott Wilson Garcia * EMail: edscott@imp.mx * * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "glade_support.h" #include "constants.h" #include "types.h" #include "icons.h" #include "add_file.h" #include "entry.h" #include "misc.h" #include "pasteboard.h" #include "settings.h" #include "xfstab.h" #define D(x) static GHashTable *icon_hash = NULL; static GtkIconFactory *icon_factory = NULL; static GtkStyle *style = NULL; static gboolean set_size_icons(GtkTreeModel * treemodel, GtkTreePath * treepath, GtkTreeIter * iter, gpointer data) { tree_details_t *tree_details = (tree_details_t *) data; tree_entry_t *en; gtk_tree_model_get(treemodel, iter, ENTRY_COLUMN, &en, -1); switch (tree_details->icon_size) { case 0: SET_SIZE_S(en->type); break; case 1: SET_SIZE_M(en->type); break; case 2: SET_SIZE_L(en->type); break; case 3: SET_SIZE_XL(en->type); break; } set_icon(tree_details->treeview, iter); return FALSE; } void reset_icons(tree_details_t * tree_details) { GtkTreeModel *treemodel = gtk_tree_view_get_model(tree_details->treeview); gtk_widget_freeze_child_notify((GtkWidget *) (tree_details->treeview)); gtk_tree_model_foreach(treemodel, set_size_icons, (gpointer) (tree_details)); gtk_widget_thaw_child_notify((GtkWidget *) (tree_details->treeview)); } GdkPixbuf *create_preview(char *file, int size) { GdkPixbuf *src, *tgt; int w, h; double scaleW, scaleH, scale; GError *error = NULL; src = gdk_pixbuf_new_from_file(file, &error); if(!src) { /*printf("DBG: pixbuf error, file=%s\n",file); */ return NULL; } if(error) g_error_free(error); switch (size) { default: w = 48, h = 24; break; case MEDIUM: w = 68, h = 34; break; case BIG: w = 100, h = 50; break; case REAL_BIG: w = 200, h = 100; break; } if (gdk_pixbuf_get_height(src) > h && gdk_pixbuf_get_width(src) > w){ scaleH = (double)h / gdk_pixbuf_get_height(src); scaleW = (double)w / gdk_pixbuf_get_width(src); scale = (scaleH < scaleW) ? scaleH : scaleW; h = scale * gdk_pixbuf_get_height(src); w = scale * gdk_pixbuf_get_width(src); } else return (src); if(w < 10 || h < 10) { if (src) g_object_unref(G_OBJECT(src)); return NULL; } if(!src) return NULL; tgt = gdk_pixbuf_scale_simple(src, w, h, GDK_INTERP_BILINEAR); if (src) g_object_unref(G_OBJECT(src)); return tgt; } GdkPixbuf *create_full_pixbuf(char *file) { GdkPixbuf *src; GError *error = NULL; src = gdk_pixbuf_new_from_file(file, &error); if(!src) { printf("DBG: pixbuf error, file=%s\n",file); return NULL; } if(error) g_error_free(error); return src; } void zap_preview(GdkPixbuf * tgt) { if (tgt) g_object_unref(G_OBJECT(tgt)); } void increase_size(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) { GtkTreeView *treeview = (GtkTreeView *) data; tree_entry_t *en = get_entry(treeview, iter); if(!en) return; if(IS_SIZE_XL(en->type)) return; else if(IS_SIZE_L(en->type)) { SET_SIZE_XL(en->type); } else if(IS_SIZE_M(en->type)) { SET_SIZE_L(en->type); } else { SET_SIZE_M(en->type); } set_icon(treeview, iter); } void decrease_size(GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data) { GtkTreeView *treeview = (GtkTreeView *) data; tree_entry_t *en = get_entry(treeview, iter); if(!en) return; if(IS_SIZE_S(en->type)) return; else if(IS_SIZE_M(en->type)) { SET_SIZE_S(en->type); } else if(IS_SIZE_L(en->type)) { SET_SIZE_M(en->type); } else if(IS_SIZE_XL(en->type)) { SET_SIZE_L(en->type); } set_icon(treeview, iter); } char *resolve_folder_icon(tree_entry_t * en) { int open; int type = en->type; if (IS_NOACCESS(en->type)){ return "xf_NOACCESS_ICON"; } if(IS_EXPANDED(type)) open = 1; else open = 0; /* exact mime type name match first (id must have _FOLDER_ substring */ if(strchr(en->path, '/')) { char *id; id = g_hash_table_lookup(icon_hash, strrchr(en->path, '/') + 1); if(id && strstr(id, "_FOLDER_")) return id; } /* link cases */ if(IS_XF_LNK(type) && IS_NOWRITE(type)) { if(open) { if(SHOWS_HIDDEN(type) && HAS_HIDDEN(type)) return "xf_AOPEN_FOLDER_RO_LNK_ICON"; else if(HAS_HIDDEN(type)) return "xf_HOPEN_FOLDER_RO_LNK_ICON"; else return "xf_OPEN_FOLDER_RO_LNK_ICON"; } else return "xf_CLOSED_FOLDER_RO_LNK_ICON"; } else if(IS_XF_LNK(type)) { if(open) { if(SHOWS_HIDDEN(type) && HAS_HIDDEN(type)) return "xf_AOPEN_FOLDER_LNK_ICON"; else if(HAS_HIDDEN(type)) return "xf_HOPEN_FOLDER_LNK_ICON"; else return "xf_OPEN_FOLDER_LNK_ICON"; } else return "xf_CLOSED_FOLDER_LNK_ICON"; } /* hard dir cases */ else if(IS_NOWRITE(type)) { if(open) { if(SHOWS_HIDDEN(type) && HAS_HIDDEN(type)) return "xf_AOPEN_FOLDER_RO_ICON"; else if(HAS_HIDDEN(type)) return "xf_HOPEN_FOLDER_RO_ICON"; else return "xf_OPEN_FOLDER_RO_ICON"; } else return "xf_CLOSED_FOLDER_RO_ICON"; } /* normal cases */ if(open) { if(SHOWS_HIDDEN(type) && HAS_HIDDEN(type)) return "xf_AOPEN_FOLDER_ICON"; else if(HAS_HIDDEN(type)) return "xf_HOPEN_FOLDER_ICON"; else return "xf_OPEN_FOLDER_ICON"; } /* the default */ return "xf_CLOSED_FOLDER_ICON"; } /* this is just to keep the icon array static */ GdkPixbuf *icon_tell_cut(int size, char *id, gboolean cut) { GtkIconSet *iconset; int gtksize; /*printf("DBG: looking for iconset %s\n",id); */ if(!icon_factory) g_assert_not_reached(); iconset = gtk_icon_factory_lookup(icon_factory, id); if(!style) style = gtk_style_new(); switch (size) { case REAL_BIG: gtksize = GTK_ICON_SIZE_DIALOG; break; case BIG: gtksize = GTK_ICON_SIZE_DND; break; case MEDIUM: default: gtksize = GTK_ICON_SIZE_LARGE_TOOLBAR; break; case SMALL: gtksize = GTK_ICON_SIZE_BUTTON; break; /*gtksize=GTK_ICON_SIZE_SMALL_TOOLBAR; break;*/ } if(!iconset) return NULL; return gtk_icon_set_render_icon(iconset, style, GTK_DIR_RIGHT, (cut) ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL, gtksize, NULL, NULL); } GdkPixbuf *icon_tell(int size, char *id) { return icon_tell_cut(size, id, FALSE); } static char *resolve_icon_id(tree_entry_t * en) { if(!en) g_assert_not_reached(); if(IS_ROOT_TYPE(en->type)) { if(IS_NETWORK_TYPE(en->type)) return ("xf_NETWORK_ICON"); else if(IS_FIND_TYPE(en->type)) return ("xf_FIND_ICON"); else if(IS_FSTAB_TYPE(en->type)) return ("xf_FSTAB_ICON"); else if(IS_APP_TYPE(en->type)) return ("xf_AGEN_ICON"); else if(IS_BOOKMARK_TYPE(en->type)) return ("xf_BOOKMARKS_ICON"); else if(IS_TRASH_TYPE(en->type)) { if(IS_EXPANDED(en->type)) return ("xf_TRASH_OPEN_ICON"); return ("xf_TRASH_CLOSED_ICON"); } else if(!IS_LOCAL_TYPE(en->type)) return (NULL); } if(IS_NETWORK_TYPE(en->type)||IS_BOOKMARK_TYPE(en->type)) { if(IS_XF_NETWG(en->subtype)) return ("xf_NETWORK_ICON"); if(IS_XF_NETWS(en->subtype)) return ("xf_NETWS_ICON"); if(IS_XF_NETSHARE(en->subtype)) { if(IS_EXPANDED(en->type)) return ("xf_SHARE_OPEN_ICON"); else return ("xf_SHARE_ICON"); } if(IS_XF_NETIPC(en->subtype)) return ("xf_IPC_ICON"); if(IS_XF_NETPRINT(en->subtype)) return ("xf_PRINTER_ICON"); if(IS_NETDIR(en->subtype)) { if (IS_EXPANDED(en->type)){ if (IS_NETREADONLY(en->subtype)) return "xf_OPEN_FOLDER_RO_ICON"; else return "xf_OPEN_FOLDER_ICON"; } else { if (IS_NETREADONLY(en->subtype)) return "xf_CLOSED_FOLDER_RO_ICON"; else return "xf_CLOSED_FOLDER_ICON"; } } } if(IS_FSTAB_TYPE(en->type) && IS_XF_FSTAB(en->type)){ if (is_mounted(en->path)==1){ /*printf("DBG:%s is mounted\n",en->path);*/ if (IS_NFS_TYPE(en->subtype)) return "xf_NFS_MNT_ICON"; if (IS_PROC_TYPE(en->subtype)) return "xf_PROCESS_MNT_ICON"; if (IS_CDFS_TYPE(en->subtype)) return "xf_CDROM_MNT_ICON"; if (strstr(en->path,"floppy")) return "xf_FLOPPY_MNT_ICON"; if (strstr(en->path,"cdrom")) return "xf_CDROM_MNT_ICON"; if (strstr(en->path,"cdrw")) return "xf_CDROM_MNT_ICON"; if (strstr(en->path,"dvd")) return "xf_DVD_MNT_ICON"; return "xf_DISK_MNT_ICON"; } else { /*printf("DBG:%s NOT mounted\n",en->path);*/ if (IS_NFS_TYPE(en->subtype)) return "xf_NFS_ICON"; if (IS_PROC_TYPE(en->subtype)) return "xf_PROCESS_ICON"; if (IS_CDFS_TYPE(en->subtype)) return "xf_CDROM_ICON"; if (strstr(en->path,"floppy")) return "xf_FLOPPY_ICON"; if (strstr(en->path,"cdrom")) return "xf_CDROM_ICON"; if (strstr(en->path,"cdrw")) return "xf_CDROM_ICON"; if (strstr(en->path,"dvd")) return "xf_DVD_ICON"; return "xf_DISK_ICON"; } } if(IS_APP_TYPE(en->type)){ /* root level doesn't get here */ return en->tag; } /* broken links : */ if(IS_BROKEN_LNK(en->type)) return "xf_BROKEN_ICON"; /* find results */ if(IS_XF_FND(en->type)) return "xf_FIND_RESULT_ICON"; if(IS_DIR(en->type)) { /*printf("folder %s link=%d\n",en->path,IS_XF_LNK(en->type)); */ /* strstr makes all folders inside wastebasket use this icon */ if(strstr(en->path, "/..Wastebasket")) { if(en->count) return "xf_WASTE_BASKET_FULL_ICON"; return "xf_WASTE_BASKET_EMPTY_ICON"; } return resolve_folder_icon(en); } /* non-broken links: */ /*printf("file %s link=%d\n",en->path,IS_XF_LNK(en->type)); */ if(IS_XF_LNK(en->type)) return "xf_LINK_ICON"; /* d_types: */ else if(IS_XF_CHR(en->type)) return ("xf_CHAR_DEV_ICON"); else if(IS_XF_BLK(en->type)) return ("xf_BLOCK_DEV_ICON"); else if(IS_XF_FIFO(en->type)) return ("xf_FIFO_ICON"); else if(IS_XF_SOCK(en->type)) return ("xf_SOCKET_ICON"); if (IS_NOACCESS(en->type)){ return ("xf_NOACCESS_ICON"); } /*if all else fails: */ return NULL; } /* *options for icons... use GTK_STATE_INSENSITIVE for files that have been cut to the pasteboard, until the pasteboard has been found invalid... * GTK_STATE_NORMAL, GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT, GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE*/ static GdkPixbuf *resolve_icon(GtkTreeView * treeview, tree_entry_t * en, tree_entry_t * p_en) { int gtksize, size; char *loc = NULL; char *id=NULL; int max_preview_size=256; gboolean cut = FALSE; tree_details_t *tree_details = get_tree_details(treeview); GdkPixbuf *Icon; GtkIconSet *iconset; char *l, *stock_id = NULL; if(!style) style = gtk_style_new(); if(IS_SIZE_XL(en->type)) { gtksize = GTK_ICON_SIZE_DIALOG; size = REAL_BIG; } else if(IS_SIZE_L(en->type)) { gtksize = GTK_ICON_SIZE_DND; size = BIG; } else if(IS_SIZE_M(en->type)) { gtksize = GTK_ICON_SIZE_LARGE_TOOLBAR; size = MEDIUM; } else { gtksize = GTK_ICON_SIZE_BUTTON; size = SMALL; } if(valid_pasteboard() == 2) { cut = in_pasteboard(en); if(cut){ SET_CUT(en->type); } } else UNSET_CUT(en->type); if (IS_CUSTOM_ICON(en->subtype)&&IS_APP_TYPE(en->type)) { GtkIconSet *icon_set; icon_set=gtk_icon_factory_lookup(icon_factory,en->tag); if (!icon_set) { GdkPixbuf *pixbuf = NULL; pixbuf = gdk_pixbuf_new_from_file(en->tag, NULL); /* printf("DBG: registering custom icon %s\n",en->tag);*/ /* GdkPixbuf *pixbuf; pixbuf = gtk_image_get_pixbuf((GtkImage *) create_pixmap(tree_details->window, en->tag));*/ icon_set = gtk_icon_set_new_from_pixbuf(pixbuf); gtk_icon_factory_add(icon_factory, en->tag, icon_set); } id = en->tag; } if (!id) id = resolve_icon_id(en); if(id) return icon_tell_cut(size, id, cut); /* image previews before executable */ if(en->path) loc = strrchr(en->path, '/'); if (getenv("XFFM_MAX_PREVIEW_SIZE") && strlen( getenv("XFFM_MAX_PREVIEW_SIZE"))){ if (is_number(getenv("XFFM_MAX_PREVIEW_SIZE"))) { max_preview_size=(atoi(getenv("XFFM_MAX_PREVIEW_SIZE"))); } } if ( !cut && loc && IS_FILE(en->type) && !IS_NETWORK_TYPE(en->type) && !IS_TRASH_TYPE(en->type) && !strstr(en->path, "/..Wastebasket") && en->st->st_size <= max_preview_size*1024 && (tree_details->preferences & IMAGE_PREVIEW || (p_en && SHOWS_IMAGES(p_en->type)) ) && IS_IMAGE(loc) ) { GdkPixbuf *tgt; /* print_status(treeview, "xf_WARNING_ICON", _("Preview"), ": ", FILENAME(en), NULL);*/ process_pending_gtk(); tgt = create_preview(en->path, size); if(tgt) return tgt; } /* mime type (before executables) : */ if(loc && strlen(loc) > 1) { l = loc + 1; loc = strrchr(l, '.'); if(loc && strlen(loc) > 1) loc++; else loc = l; if (IS_NETFILE(en->subtype) && (strcmp(loc,"exe")==0 || strcmp(loc,"EXE")==0 || strcmp(loc,"com")==0 || strcmp(loc,"COM")==0 || strcmp(loc,"bat")==0 ||strcmp(loc,"BAT")==0 ) ) return icon_tell_cut(size, "xf_EXECUTABLE_ICON", cut); stock_id = g_hash_table_lookup(icon_hash, loc); if(!stock_id && strchr(loc, '-')) { /* try for a backup icon */ char *a, *aloc = g_strdup(loc); if((a = strtok(aloc, "-")) != NULL) { stock_id = g_hash_table_lookup(icon_hash, a); } g_free(aloc); aloc=NULL; } if(!stock_id && strchr(loc, '~')) { /* try for another backup icon */ char *a, *aloc = g_strdup(loc); if((a = strtok(aloc, "~")) != NULL) { stock_id = g_hash_table_lookup(icon_hash, a); } g_free(aloc); aloc=NULL; } if(stock_id) { iconset = gtk_icon_factory_lookup(icon_factory, stock_id); if (!iconset) iconset = gtk_icon_factory_lookup(icon_factory, "xf_default"); if(iconset) { Icon = gtk_icon_set_render_icon(iconset, style, GTK_DIR_RIGHT, (cut) ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL, gtksize, NULL, NULL); return Icon; } } } /* by mode, (executables, read-only, noaccess): */ if(IS_EXE(en->type)){ if (!IS_NETWORK_TYPE(en->type) && !IS_NETTHING(en->subtype)){ /* try for shell types */ char what[32]; FILE *file=fopen(en->path,"rb"); if (file){ if (fread((void *)what,1,32,file)){ fclose(file); what[31]=0; if (strstr(what,"/bin/sh")) return icon_tell_cut(size, "xf_text-x-sh", cut); if (strstr(what,"/bin/ksh")) return icon_tell_cut(size, "xf_text-x-ksh", cut); if (strstr(what,"/bin/csh")) icon_tell_cut(size, "xf_text-x-csh", cut); if (strstr(what,"/bin/bsh")) return icon_tell_cut(size, "xf_text-x-bsh", cut); if (strstr(what,"/bin/bash")) return icon_tell_cut(size, "xf_text-x-bsh", cut); if (strstr(what,"/bin/zsh")) return icon_tell_cut(size, "xf_text-x-zsh", cut); if (strstr(what,"/bin/tsh")) return icon_tell_cut(size, "xf_text-x-xsh", cut); if (strstr(what,"/usr/bin/perl")) return icon_tell_cut(size, "xf_text-x-perl", cut); } } } return icon_tell_cut(size, "xf_EXECUTABLE_ICON", cut); } if(IS_NOWRITE(en->type)){ if (gtk_icon_factory_lookup(icon_factory, "xf_no-write")) return icon_tell_cut(size, "xf_no-write", cut); } /* all else has failed, return the default icon */ return icon_tell_cut(size, "xf_DEFAULT_ICON", cut); } GdkPixbuf *resolve_icon_small(tree_entry_t * en) { int gtksize, size; static GtkStyle *style = NULL; char *loc; char *id; if(!en || !en->path) return NULL; if(!style) style = gtk_style_new(); gtksize = GTK_ICON_SIZE_LARGE_TOOLBAR; size = SMALL; id = resolve_icon_id(en); if(!id && IS_EXE(en->type)) id = "xf_EXECUTABLE_ICON"; if(id) return icon_tell(size, id); /* mime type: */ loc = strrchr(en->path, '/'); if(loc) { GdkPixbuf *Icon; GtkIconSet *iconset; char *l, *stock_id = NULL; l = loc + 1; loc = strrchr(l, '.'); if(!loc) loc = l; else loc++; stock_id = g_hash_table_lookup(icon_hash, loc); if(stock_id) { iconset = gtk_icon_factory_lookup(icon_factory, stock_id); if(!iconset) return NULL; Icon = gtk_icon_set_render_icon(iconset, style, GTK_DIR_RIGHT, GTK_STATE_NORMAL, gtksize, NULL, NULL); return Icon; } /*else printf("key=%s not found loco\n",loc); */ } return icon_tell(size, "xf_DEFAULT_ICON"); } void set_icon(GtkTreeView * treeview, GtkTreeIter * iterator) { GdkPixbuf *Icon; GtkTreeModel *treemodel = gtk_tree_view_get_model(treeview); tree_entry_t *en = get_entry(treeview, iterator); tree_entry_t *p_en = NULL; GtkTreeIter parent; if(gtk_tree_model_iter_parent(treemodel, &parent, iterator)) gtk_tree_model_get(treemodel, &parent, ENTRY_COLUMN, &p_en, -1); D("setting icon\n") if(!en) return; if(IS_DUMMY_TYPE(en->type)) return; /*if (en->path) printf("DBG: icon setting for %s\n",en->path); */ set_font(treeview,iterator); Icon = resolve_icon(treeview, en, p_en); gtk_tree_store_set((GtkTreeStore *) treemodel, iterator, PIXBUF_COLUMN, Icon, -1); if (Icon) g_object_unref (G_OBJECT (Icon)); } void update_icon(GtkTreeView * treeview, GtkTreeIter * iterator) { GdkPixbuf *Icon; GtkTreeModel *treemodel = gtk_tree_view_get_model(treeview); tree_entry_t *en = get_entry(treeview, iterator); tree_details_t *tree_details = get_tree_details(treeview); tree_entry_t *p_en = NULL; GtkTreeIter parent; if(gtk_tree_model_iter_parent(treemodel, &parent, iterator)) gtk_tree_model_get(treemodel, &parent, ENTRY_COLUMN, &p_en, -1); if(!tree_details || !tree_details->window) return; if(!en) return; if(IS_DUMMY_TYPE(en->type) || IS_XF_BLK(en->type) || IS_XF_CHR(en->type)) return; if(IS_DIR(en->type)) { struct stat st; stat(en->path, &st); if(st.st_mtime != en->st->st_mtime || st.st_ctime != en->st->st_ctime) { memcpy(en->st, &st, sizeof(struct stat)); en->count = count_files(en->path); Icon = resolve_icon(treeview, en, p_en); D(".") gtk_tree_store_set((GtkTreeStore *) treemodel, iterator, PIXBUF_COLUMN, Icon, SIZE_COLUMN, sizetag(-1, en->count), -1); if (Icon) g_object_unref (G_OBJECT (Icon)); } } if(IS_CUT(en->type) || in_pasteboard(en)) { /*printf("dbg update icon %s\n",en->path); */ Icon = resolve_icon(treeview, en, p_en); gtk_tree_store_set((GtkTreeStore *) treemodel, iterator, PIXBUF_COLUMN, Icon, -1); if (Icon) g_object_unref (G_OBJECT (Icon)); if(in_pasteboard(en)) SET_CUT(en->type); else UNSET_CUT(en->type); } return; } /* defined in src/glade_support.c, but not exported */ extern void clear_pixmap_directory (void); /*#define DEBUG*/ void create_icons(tree_details_t * tree_details) { GtkIconSet *icon_set; GdkPixbuf *pixbuf; xmlChar *id, *value; xmlNodePtr node; xmlDocPtr doc; gchar *mimefile; gchar *icon_dir,*theme_dir; gchar *typesfile; /* to have a clean icon factory you must create a new one. * there is no gtk instruction to remove the old icon factory (gtkbug) * if (!icon_factory) */ #ifdef DEBUG printf("DBG: entering create_icons\n"); #endif if (!tree_details->theme) tree_details->theme=g_strdup("gnome"); typesfile=g_strconcat(PACKAGE_DATA_DIR,"/",PACKAGE, "/pixmaps/types.xml",NULL); mimefile=g_strconcat(PACKAGE_DATA_DIR,"/",PACKAGE,"/pixmaps/", tree_details->theme,"/mime.xml",NULL); if (access(mimefile,F_OK)!=0){ /* fall back to plain */ printf("xffm: %s theme not found. Using plain icons instead.\n", tree_details->theme); printf(" Install package xffm-icons for richer icons.\n"); printf(" Or select \"plain\" theme to remove this warning.\n"); fflush(NULL); g_free(mimefile); mimefile=NULL; mimefile=g_strconcat(PACKAGE_DATA_DIR,"/",PACKAGE, "/pixmaps/plain/mime.xml",NULL); } icon_factory = gtk_icon_factory_new(); icon_hash = g_hash_table_new(g_str_hash, g_str_equal); /* defined in src/glade_support.c, but not exported */ clear_pixmap_directory(); icon_dir=g_strconcat(PACKAGE_DATA_DIR,"/",PACKAGE,"/pixmaps",NULL); theme_dir=g_strconcat(icon_dir,"/",tree_details->theme,NULL); if (access(theme_dir,X_OK)!=0){ g_free(theme_dir); theme_dir=NULL; theme_dir=g_strconcat(PACKAGE_DATA_DIR,"/",PACKAGE, "/pixmaps/plain",NULL); } /* search order is FILO */ add_pixmap_directory(icon_dir); #ifdef DEBUG printf("DBG: adding pixmapdir=%s\n",theme_dir); #endif { char **themes, **t; t = themes = find_themes(theme_dir); for(t = themes; *t; t++) { gchar *subdir=g_strconcat(theme_dir,"/",*t,NULL); add_pixmap_directory(subdir); #ifdef DEBUG printf("DBG: adding pixmapdir=%s\n",subdir); #endif g_free(subdir); subdir=NULL; g_free(*t); *t=NULL; } g_free(themes); themes=NULL; } add_pixmap_directory(theme_dir); g_free(theme_dir); theme_dir=NULL; #ifdef DEBUG printf("DBG: adding pixmapdir=%s\n",icon_dir); #endif g_free(icon_dir); icon_dir=NULL; xmlKeepBlanksDefault(0); if((doc = xmlParseFile(typesfile)) == NULL) { error2_xml: printf("xffm: No valid type.xml found.\n"); printf(" It should be at %s\n", typesfile); printf(" Verify your program instalation, dude!\n"); fflush(NULL); goto time2return; /*g_assert_not_reached();*/ } node = xmlDocGetRootElement(doc); if(!xmlStrEqual(node->name, (const xmlChar *)"mime_types")) { xmlFreeDoc(doc); goto error2_xml; } /* Now parse the xml tree */ #ifdef DEBUG printf("DBG: parsing %s\n",typesfile); #endif for(node = node->children; node; node = node->next) { if(xmlStrEqual(node->name, (const xmlChar *)"type")) { id = xmlGetProp(node, (const xmlChar *)"id"); value = xmlGetProp(node, (const xmlChar *)"ext"); g_hash_table_insert(icon_hash, g_strdup(value), (gpointer) g_strdup(id)); #ifdef DEBUG fprintf(stderr,"DBG:adding type: %s %s\n",value,id); #endif g_free(value); value=NULL; g_free(id); id=NULL; } } xmlFreeDoc(doc); if((doc = xmlParseFile(mimefile)) == NULL) { error_xml: printf("xffm: No valid mime.xml found for theme.\n"); printf("xffm: It should be at %s\n", mimefile); printf("xffm: Verify your program instalation, dude!\n"); goto time2return; /*g_assert_not_reached();*/ } node = xmlDocGetRootElement(doc); if(!xmlStrEqual(node->name, (const xmlChar *)"mime_types")) { xmlFreeDoc(doc); goto error_xml; } /* Now parse the xml tree */ #ifdef DEBUG printf("DBG: parsing %s\n",mimefile); #endif for(node = node->children; node; node = node->next) { if(xmlStrEqual(node->name, (const xmlChar *)"mime")) { id = xmlGetProp(node, (const xmlChar *)"id"); value = xmlGetProp(node, (const xmlChar *)"icon"); #ifdef DEBUG fprintf(stderr,"DBG:adding icon: %s %s\n",value,id); #endif if(strncmp("gtk-", value, strlen("gtk-")) == 0) pixbuf = gtk_widget_render_icon(tree_details->window, value, GTK_ICON_SIZE_DIALOG, NULL); else pixbuf = gtk_image_get_pixbuf((GtkImage *) create_pixmap(tree_details->window, value)); icon_set = gtk_icon_set_new_from_pixbuf(pixbuf); gtk_icon_factory_add(icon_factory, id, icon_set); g_free(value); value=NULL; g_free(id); id=NULL; } if(xmlStrEqual(node->name, (const xmlChar *)"search")){ id = xmlGetProp(node, (const xmlChar *)"path"); /*printf("DBG: *****************looking for %s\n",id);*/ if (access(id,F_OK)==0) { add_pixmap_directory(id); /*printf("DBG: adding %s\n",id);*/ } g_free(id); id=NULL; } } xmlFreeDoc(doc); time2return: g_free(mimefile); mimefile=NULL; g_free(typesfile); typesfile=NULL; return; } GtkWidget *icon_image(char *id) { if(id) { GdkPixbuf *Icon; GtkIconSet *iconset; if(!style) style = gtk_style_new(); iconset = gtk_icon_factory_lookup(icon_factory, id); if(!iconset) return NULL; Icon = gtk_icon_set_render_icon(iconset, style, GTK_DIR_RIGHT, GTK_STATE_NORMAL, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL, NULL); if(Icon) return gtk_image_new_from_pixbuf(Icon); } return NULL; } void set_mainmenu_icons(tree_details_t * tree_details) { GtkWidget *image4745; GtkWidget *w; char *names[] = { "menuitem1", "menuitem2", "hide_show1", "go1", "preferences3", "menuitem4", NULL }; char *iconos[] = { "xf_FILE_ICON", "xf_EDIT_ICON", "xf_VIEW_ICON", "xf_GO_ICON", "xf_PREFERENCES_ICON", "xf_HELP_ICON", NULL }; int i = 0; for(i = 0; names[i]; i++) { image4745 = icon_image(iconos[i]); if(image4745) gtk_widget_show(image4745); w = lookup_widget(tree_details->window, names[i]); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(w), image4745); } } static void clear_iconset(gpointer key, gpointer value, gpointer user_data) { g_free(key); key=NULL; g_free(value); value=NULL; } void recreate_icons(tree_details_t * tree_details) { g_hash_table_foreach(icon_hash, clear_iconset, NULL); g_hash_table_destroy(icon_hash); /* create new icons */ create_icons(tree_details); /* reset icons */ set_mainmenu_icons(tree_details); reset_icons(tree_details); } /* FIXME: enable full size previews */ void on_full_preview1_activate(GtkMenuItem * menuitem, gpointer user_data) { }