Programming and Scripting :: XPM Icon Viewer



I think this works. It should ignore *.xpm and *.XPM files that are not actually XPMs

Code Sample
#!/bin/murgaLua

-- XPM icon viewer
-- mikshaw 2007
-- thanks to ^thehatsrule^ and jpeters for help and suggestions

-- start directory
dir="/usr/share/dfm/icons"
-- icon editor (text editors and image editors both work)
editor="xpaint"
-- maximum icon size
xpm_size=48

broken_xpm_data=[[
/* XPM */
static char *broken_image[] = {
/* columns rows colors chars-per-pixel */
"16 16 4 1",
"  c red",
". c #C4BF91",
"X c #FFF8D6",
"o c None",
/* pixels */
"ooo..........ooo",
"ooo. XXXXX X.ooo",
"ooo.  XXX  X.ooo",
"ooo.X  X  XX.ooo",
"ooo.XX   XXX.ooo",
"ooo.X  X  XX.ooo",
"ooo.  XXX  Xoooo",
"ooo. XXXXo ooooo",
"ooo.XXXXoooooooo",
"ooo.XoXooooooooo",
"ooo.oooooooo.ooo",
"oooooooooXoX.ooo",
"ooooooooXXXX.ooo",
"oooooXoXXXXX.ooo",
"ooooXXXXXXXX.ooo",
"ooo..........ooo"
};
]]
xpm_tempfile=os.tmpname()
xpm_write=io.open(xpm_tempfile,"w")
if xpm_write then
 xpm_write:write(broken_xpm_data)
 xpm_write:close()
 broken_xpm=fltk:Fl_XPM_Image(xpm_tempfile)
 os.remove(xpm_tempfile)
end

edvar=os.getenv("XPM_EDITOR")
if edvar then editor=edvar end

function get_image_data(self)
 local old_data=display:image()
 if old_data then old_data:uncache() end
 local image_data=self:image()
 if image_data then
   display:image(image_data:copy(128,128)) --show it bigger!
   broken=nil
   i_menu:mode(3,1) -- disable "fix" item
 else
   display:image(broken_xpm)
   broken=self:tooltip()
   i_menu:mode(3,0)
 end
 current_file=dir..self:tooltip() -- for editor
 display:label("\n"..self:tooltip().."\n"..lfs.attributes(current_file).size.." bytes")
 display:redraw()
end

function menu_cb()
 local v=i_menu:value()
 if v==0 and current_file then os.execute(editor.." "..current_file.." &")
 elseif v==1 then chdir()
 elseif v==2 then refresh()
 elseif v==3 then fix_xpm()
 elseif v==4 then os.exit(0)
 end
end

function find_stupid_space(infile)
 is_xpm,space_found=0,0
 local data=io.open(infile)
 if data then
   for line in data:lines() do
     -- is it really an xpm file
     if string.find(line,"/%*%s*XPM%s*%*/") then is_xpm=1 end
     -- is it going to break murgaLua
     if string.find(line,"^%s") then space_found=1; break end
   end
   data:close()
   return is_xpm,space_found
 end
end

function build_list(dfile)
 local active=1
 if not string.find(dir,"/$") then dir=dir.."/" end
 scroll=fltk:Fl_Scroll(5,bh,sw,sh)
 w:add(scroll)
 pack=fltk:Fl_Pack(5,bh,bw,sh)
 pack:spacing(2)
 scroll:add(pack)
 -- get all xpm files
 for file in lfs.dir(dir) do
   if string.find(string.lower(file),"%.xpm$") then
     table.insert(images,file)
   end
 end
 table.sort(images)
 -- make buttons for "xpm_size" images only
 xpm_count=0
 filesize=0
 for i=1,table.getn(images) do
   local is_xpm,space_found=find_stupid_space(dir..images[i])
   if is_xpm==1 then --if it's a true xpm
     icon[i]=fltk:Fl_XPM_Image(dir..images[i])
     if icon[i]:w()<=xpm_size and icon[i]:h()<=xpm_size then
         xpm_count=1+xpm_count
         filesize=filesize+lfs.attributes(dir..images[i]).size
         butt[xpm_count]=fltk:Fl_Button(0,0,bw,bw)
         butt[xpm_count]:box(15) --shadow
       if space_found==0 then
         butt[xpm_count]:image(icon[i])
       else butt[xpm_count]:label("bad\nimage")
       end
         butt[xpm_count]:callback(get_image_data)
         butt[xpm_count]:tooltip(images[i])
         if broken==images[i] or dfile==images[i] then active=xpm_count end -- for refreshing display
         pack:add(butt[xpm_count])
       else icon[i]:uncache()
     end
   end
 end
 if butt[active] then
   -- show first image
   display:show()
   butt[active]:do_callback()
 end
 display2:label(xpm_count.." files | "..math.ceil(filesize/1024).." kb")
end

function refresh()
 local old_image=display:image()
 if old_image then old_image:uncache(); display:hide() end
 -- clear all tables and remove buttons
 for i=1,table.getn(images) do table.remove(images) end
 for i=1,table.getn(icon) do icon[i]:uncache() end
 for i=1,table.getn(icon) do table.remove(icon) end
 for i=1,table.getn(butt) do table.remove(butt) end
 w:remove(scroll)
 Fl:delete_widget(scroll)
 scroll=nil
 build_list()
end

function chdir()
 local dirname=fltk.fl_dir_chooser("pick a dir...",dir)
 if dirname then
   dir=dirname
   refresh()
 end
end

function fix_xpm()
 if broken then
   os.execute("cd "..dir.." && sxpm -nod "..broken.." -o "..broken)
   refresh()
 end
end

function open_file(what)
if lfs.attributes(what).mode=="directory" then
 dir=what
else
 dragfile=fltk.fl_filename_name(what)
 dir=string.gsub(what,"(.*/).*$","%1")
end
build_list(dragfile)
end

-- candy
Fl:set_boxtype(fltk.FL_UP_BOX,fltk.FL_THIN_UP_BOX)
Fl:set_boxtype(fltk.FL_DOWN_BOX,fltk.FL_THIN_DOWN_BOX)
fltk.fl_define_FL_SHADOW_BOX()
Fl:set_color(fltk.FL_DARK3,150,150,150) -- shadow
Fl:set_color(fltk.FL_GRAY0,128,128,128) -- frame
--Fl_Tooltip:disable()

-- some sizes and positions are determined by xpm_size
bw=xpm_size+20 -- button width
bh=30; sw=bw+20; sh=250 -- menu, scroll size
ww=sw+sh+10
wh=bh+sh+10
images={}; icon={}; butt={}
w=fltk:Fl_Window(ww,wh,"XPM Icons")

menu_items={"&Edit","&Directory","&Refresh","&Fix","&Quit"}
i_menu=fltk:Fl_Menu_Button(0,0,sw+5,bh,"&Menu")
i_menu:align(20)
i_menu:callback(menu_cb)
i_menu:selection_color(fltk.FL_WHITE)
for i,v in ipairs(menu_items) do i_menu:add(v) end

display=fltk:Fl_Box(sw+5,0,sh,sh) -- big image
display2=fltk:Fl_Box(sw+5,sh,sh,bh) -- dir info

if arg[1] then open_file(arg[1]) else build_list() end -- drag and drop
w:show()
Fl:run()

I was curious where the info regarding the path for individual dfm app icons is stored (the one listed in options)
If I understand your question, you want to know why it says "/usr/share/dfm/icons/blah.xpm" when you make a new icon? There are two files involved.
The file .dfmext (which you might need to create or copy) store info for default file type icons. The file .dfminfo is a gzipped text file that contains paths and locations for user-created and user-modified icons. This file is managed by dfm itself.

I think there might be some hardwired paths in the application, but I'm not sure.

Quote (mikshaw @ Nov. 04 2007,14:22)
The file .dfminfo is a gzipped text file that contains paths and locations for user-created and user-modified icons.


.. okay, so the path to the desktop icon is listed after  "$name_ICON;"  where $name is the name on the icon.  It might be a nice feature if this path (to the icon directory) could be used with DND (assuming there's easy code to get the name) vs the app's desktop directory. I can already load any directory of xpm's via the XPM_viewer's menu.

I guess I'm still not sure what you're getting at. Are you talking about this script here or only dfm?

Quote
I can already load any directory of xpm's via the XPM_viewer's menu
But this is the only purpose for dragging with this script, and likely will remain that way. The script is made for XPM image files themselves, and has no relationship to the applications associated with those files in dfm. The dfm application already has the tools necessary to deal with the connection between applications and icons. This script is intended to view your XPM files (xzgv doesn't support xpm) and optionally open up an editor for the selected icon. I have no intention of integrating it into a particular desktop environment.

Next Page...
original here.