Skip to content

Commit

Permalink
Added dirs and files icons to Desktop
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanoverna authored and terceiro committed Feb 21, 2009
1 parent 5520625 commit 6b9efb9
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 31 deletions.
47 changes: 40 additions & 7 deletions freedesktop/desktop.lua
Expand Up @@ -12,7 +12,7 @@ module("freedesktop.desktop")

local current_pos = {}
local iconsize = { width = 48, height = 48 }
local labelsize = { width = 100, height = 20 }
local labelsize = { width = 130, height = 20 }
local margin = { x = 20, y = 20 }

function add_icon(settings)
Expand Down Expand Up @@ -51,7 +51,8 @@ function add_icon(settings)
end

if (settings.label) then
caption = widget({ type="textbox", align="right" })
caption = widget({ type="textbox", align="right", width=labelsize.width })
caption.ellipsize = "middle"
caption.text = settings.label
caption:buttons({
button({ }, 1, settings.click)
Expand All @@ -71,11 +72,18 @@ function add_icon(settings)
current_pos[s].y = current_pos[s].y + labelsize.height + margin.y
end

function add_desktop_icons(arg)
for i, program in ipairs(utils.parse_dir('~/Desktop',
{ iconsize.width .. "x" .. iconsize.height,
"128x128", "96x96", "72x72", "64x64", "48x48",
"36x36", "32x32", "24x24", "22x22", "16x16" })) do
--- Adds subdirs and files icons to the desktop
-- @param dir The directory to parse, (default is ~/Desktop)
-- @param showlabels Shows icon captions (default is false)
function add_applications_icon(arg)
for i, program in ipairs(utils.parse_desktop_files({
dir = arg.dir or '~/Desktop/',
icon_sizes = {
iconsize.width .. "x" .. iconsize.height,
"128x128", "96x96", "72x72", "64x64", "48x48",
"36x36", "32x32", "24x24", "22x22", "16x6"
}
})) do
if program.show then
add_icon({
label = arg.showlabels and program.Name or nil,
Expand All @@ -87,3 +95,28 @@ function add_desktop_icons(arg)
end
end

--- Adds subdirs and files icons to the desktop
-- @param dir The directory to parse
-- @param showlabels Shows icon captions
-- @param open_with The program to use to open clicked files and dirs (i.e. xdg_open, thunar, etc.)
function add_dirs_and_files_icon(arg)
arg.open_with = arg.open_width or 'thunar'
for i, file in ipairs(utils.parse_dirs_and_files({
dir = arg.dir or '~/Desktop/',
icon_sizes = {
iconsize.width .. "x" .. iconsize.height,
"128x128", "96x96", "72x72", "64x64", "48x48",
"36x36", "32x32", "24x24", "22x22", "16x6"
}
})) do
if file.show then
add_icon({
label = arg.showlabels and file.filename or nil,
icon = file.icon,
screen = arg.screen,
click = function () awful.util.spawn(arg.open_with .. ' ' .. file.path) end
})
end
end
end

31 changes: 16 additions & 15 deletions freedesktop/menu.lua
@@ -1,13 +1,13 @@
-- Grab environment
local utils = require("freedesktop.utils")
local io = io
local ipairs = ipairs
local string = string
local table = table
local os = os

module("freedesktop.menu")
module("freedesktop.menu", package.seeall)

-- the categories and their synonyms where shamelessly copied from lxpanel
-- the categories and their synonims where shamelessly copied from lxpanel
-- source code.

programs = {}
Expand All @@ -25,7 +25,7 @@ programs['System'] = {}
programs['Utility'] = {}
programs['Other'] = {}

for i, program in ipairs(utils.parse_dir('/usr/share/applications/')) do
for i, program in ipairs(utils.parse_desktop_files({ dir = '/usr/share/applications/' })) do

-- check whether to include in the menu
if program.show and program.Name and program.cmdline then
Expand All @@ -48,15 +48,16 @@ for i, program in ipairs(utils.parse_dir('/usr/share/applications/')) do
end

applications_menu = {
{ "Accessories", programs["Utility"], utils.lookup_icon({ icon = 'applications-accessories.png' }) },
{ "Development", programs["Development"], utils.lookup_icon({ icon = 'applications-development.png' }) },
{ "Education", programs["Education"], utils.lookup_icon({ icon = 'applications-science.png' }) },
{ "Games", programs["Game"], utils.lookup_icon({ icon = 'applications-games.png' }) },
{ "Graphics", programs["Graphics"], utils.lookup_icon({ icon = 'applications-graphics.png' }) },
{ "Internet", programs["Network"], utils.lookup_icon({ icon = 'applications-internet.png' }) },
{ "Multimedia", programs["AudioVideo"], utils.lookup_icon({ icon = 'applications-multimedia.png' }) },
{ "Office", programs["Office"], utils.lookup_icon({ icon = 'applications-office.png' }) },
{ "Other", programs["Other"], utils.lookup_icon({ icon = 'applications-other.png' }) },
{ "Settings", programs["Settings"], utils.lookup_icon({ icon = 'applications-utilities.png' }) },
{ "System Tools", programs["System"], utils.lookup_icon({ icon = 'applications-system.png' }) },
{ "Accessories", programs["Utility"], utils.lookup_application_icon({ icon = 'applications-accessories.png' }) },
{ "Development", programs["Development"], utils.lookup_application_icon({ icon = 'applications-development.png' }) },
{ "Education", programs["Education"], utils.lookup_application_icon({ icon = 'applications-science.png' }) },
{ "Games", programs["Game"], utils.lookup_application_icon({ icon = 'applications-games.png' }) },
{ "Graphics", programs["Graphics"], utils.lookup_application_icon({ icon = 'applications-graphics.png' }) },
{ "Internet", programs["Network"], utils.lookup_application_icon({ icon = 'applications-internet.png' }) },
{ "Multimedia", programs["AudioVideo"], utils.lookup_application_icon({ icon = 'applications-multimedia.png' }) },
{ "Office", programs["Office"], utils.lookup_application_icon({ icon = 'applications-office.png' }) },
{ "Other", programs["Other"], utils.lookup_application_icon({ icon = 'applications-other.png' }) },
{ "Settings", programs["Settings"], utils.lookup_application_icon({ icon = 'applications-utilities.png' }) },
{ "System Tools", programs["System"], utils.lookup_application_icon({ icon = 'applications-system.png' }) },
}

153 changes: 144 additions & 9 deletions freedesktop/utils.lua
Expand Up @@ -12,7 +12,9 @@ icon_theme = nil

all_icon_sizes = { '16x16', '22x22', '24x24', '32x32', '36x36', '48x48', '64x64', '72x72', '96x96', '128x128' }

local function file_exists(filename)
local mime_types = {}

function file_exists(filename)
local file = io.open(filename, 'r')
local result = (file ~= nil)
if result then
Expand All @@ -21,7 +23,7 @@ local function file_exists(filename)
return result
end

function lookup_icon(arg)
function lookup_application_icon(arg)
if arg.icon:sub(1, 1) == '/' and (arg.icon:find('.+%.png') or arg.icon:find('.+%.xpm')) then
-- icons with absolute path and supported (AFAICT) formats
return arg.icon
Expand Down Expand Up @@ -60,13 +62,113 @@ function lookup_icon(arg)
end
end

function lookup_directory_icon(arg)
local icon_path = {}
local icon_theme_paths = {}
if icon_theme then
table.insert(icon_theme_paths, '/usr/share/icons/' .. icon_theme .. '/')
-- TODO also look in parent icon themes, as in freedesktop.org specification
end
table.insert(icon_theme_paths, '/usr/share/icons/hicolor/') -- fallback theme cf spec

for i, icon_theme_directory in ipairs(icon_theme_paths) do
for j, size in ipairs(arg.icon_sizes or all_icon_sizes) do
table.insert(icon_path, icon_theme_directory .. size .. '/places/')
end
end

for i, directory in ipairs(icon_path) do
local filepath_png = directory .. arg.type .. '.png'
local filepath_xpm = directory .. arg.type .. '.xpm'
if (file_exists(filepath_png)) then return filepath_png end
if (file_exists(filepath_xpm)) then return filepath_xpm end
end

if type ~= 'folder' then
return lookup_directory_icon({
type = 'folder',
icon_sizes = arg.icon_sizes or all_icon_sizes
})
end
end

function lookup_file_icon(arg)
load_mime_types()

local extension = arg.filename:match('%a+$')
local mime = mime_types[extension] or ''
local mime_family = mime:match('^%a+') or ''

local icon_path = {}
local icon_theme_paths = {}
if icon_theme then
table.insert(icon_theme_paths, '/usr/share/icons/' .. icon_theme .. '/')
-- TODO also look in parent icon themes, as in freedesktop.org specification
end
table.insert(icon_theme_paths, '/usr/share/icons/hicolor/') -- fallback theme cf spec

for i, icon_theme_directory in ipairs(icon_theme_paths) do
for j, size in ipairs(arg.icon_sizes or all_icon_sizes) do
table.insert(icon_path, icon_theme_directory .. size .. '/mimetypes/')
end
end

for i, directory in ipairs(icon_path) do

-- possible icons in a typical gnome theme (i.e. Tango icons)
local possible_filenames = {
mime,
'gnome-mime-' .. mime,
mime_family,
'gnome-mime-' .. mime_family,
extension
}

for i, filename in ipairs(possible_filenames) do
local filepath_png = directory .. filename .. '.png'
local filepath_xpm = directory .. filename .. '.xpm'
if (file_exists(filepath_png)) then return filepath_png end
if (file_exists(filepath_xpm)) then return filepath_xpm end
end
end

-- If we don't find ad icon, then pretend is a plain text file
if extension ~= 'txt' then
return lookup_file_icon({
filename = 'dummy.txt',
icon_sizes = arg.icon_sizes or all_icon_sizes
})
end

end

--- Load system MIME types
-- @return A table with file extension <--> MIME type mapping
function load_mime_types()
if #mime_types == 0 then
for line in io.lines('/etc/mime.types') do
if not line:find('^#') then
local parsed = {}
for w in line:gmatch('[^%s]+') do
table.insert(parsed, w)
end
if #parsed > 1 then
for i = 2, #parsed do
mime_types[parsed[i]] = parsed[1]:gsub('/', '-')
end
end
end
end
end
end

--- Parse a .desktop file
-- @param file The .desktop file
-- @param requested_icon_sizes A list of icon sizes (optional). If this list is given, it will be used as a priority list for icon sizes when looking up for icons. If you want large icons, for example, you can put '128x128' as the first item in the list.
-- @return A table with file entries.
function parse(file, requested_icon_sizes)
local program = { show = true, file = file }
for line in io.lines(file) do
function parse_desktop_file(arg)
local program = { show = true, file = arg.file }
for line in io.lines(arg.file) do
for key, value in line:gmatch("(%w+)=(.+)") do
program[key] = value
end
Expand All @@ -80,7 +182,7 @@ function parse(file, requested_icon_sizes)

-- Look up for a icon.
if program.Icon then
program.icon_path = lookup_icon({ icon = program.Icon, icon_sizes = (requested_icon_sizes or all_icon_sizes) })
program.icon_path = lookup_application_icon({ icon = program.Icon, icon_sizes = (arg.icon_sizes or all_icon_sizes) })
end

-- Split categories into a table.
Expand Down Expand Up @@ -111,11 +213,44 @@ end
-- @param dir The directory.
-- @param icons_size, The icons sizes, optional.
-- @return A table with all .desktop entries.
function parse_dir(dir, icon_sizes)
function parse_desktop_files(arg)
local programs = {}
local files = io.popen('find '.. dir ..' -maxdepth 1 -name "*.desktop"'):lines()
local files = io.popen('find '.. arg.dir ..' -maxdepth 1 -name "*.desktop"'):lines()
for file in files do
table.insert(programs, parse(file, icon_sizes))
arg.file = file
table.insert(programs, parse_desktop_file(arg))
end
return programs
end

--- Parse a directory files and subdirs
-- @param dir The directory.
-- @param icons_size, The icons sizes, optional.
-- @return A table with all .desktop entries.
function parse_dirs_and_files(arg)
local files = {}
local paths = io.popen('find '..arg.dir..' -maxdepth 1 -type d'):lines()
for path in paths do
if path:match("[^/]+$") then
local file = {}
file.filename = path:match("[^/]+$")
file.path = path
file.show = true
file.icon = lookup_directory_icon({ type="folder", icon_sizes = arg.icon_sizes or all_icon_sizes })
table.insert(files, file)
end
end
local paths = io.popen('find '..arg.dir..' -maxdepth 1 -type f'):lines()
for path in paths do
if not path:find("\.desktop$") then
local file = {}
file.filename = path:match("[^/]+$")
file.path = path
file.show = true
file.icon = lookup_file_icon({ filename = file.filename, icon_sizes = arg.icon_sizes or all_icon_sizes })
table.insert(files, file)
end
end
return files
end

0 comments on commit 6b9efb9

Please sign in to comment.