diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-04-21 20:55:44 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-04-21 20:55:44 +0000 |
commit | 5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0 (patch) | |
tree | 7845e677b2b36c3f8090b7e424284a28fa397713 /lib/menubuilder.lua | |
parent | ed9bf961c16e1f9d58f39ebb1afc289e5564ebfe (diff) | |
download | acf-core-5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0.tar.bz2 acf-core-5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0.tar.xz |
Ted's Logon/permissions changes
git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@1030 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'lib/menubuilder.lua')
-rw-r--r-- | lib/menubuilder.lua | 214 |
1 files changed, 86 insertions, 128 deletions
diff --git a/lib/menubuilder.lua b/lib/menubuilder.lua index 1d4c974..c7ff075 100644 --- a/lib/menubuilder.lua +++ b/lib/menubuilder.lua @@ -10,157 +10,115 @@ module(..., package.seeall) -- startdir should be the app dir. local get_candidates = function (startdir) local t = {} - startdir = startdir .. "/" local fh = io.popen('find ' .. startdir .. ' -name "*.menu"') - - local start = string.gsub(startdir, "/$", "") for x in fh:lines() do - table.insert (t, (string.gsub(x, start, ""))) + t[#t + 1] = x end - return t end +-- Split string into priority and name, convert '_' to space +local parse_menu_entry = function (entry) + local name, priority + if (string.match(entry, "^%d")) then + priority, name = string.match(entry, "(%d+)(.*)") + else + name = entry + end + name = string.gsub(name, "_", " ") + return name, priority +end --- internal function for table.sort -local t_compare = function (x,y,f) - for k,v in pairs(f) do - local a = x[v] - local b = y[v] - if tonumber(a) and tonumber(b) then - a=tonumber(a) - b=tonumber(b) - end - if a < b then return true end - if a > b then return false end +-- Parse menu file entry, returning cat, group, tab, action and priorities +local parse_menu_line = function (line) + local result = nil + --skip comments and blank lines + if nil == (string.match(line, "^#") or string.match(line,"^$")) then + local item = {} + for i in string.gmatch(line, "%S+") do + item[#item + 1] = i end - return false - end - --- Returns a table of all submenu items found --- Displayorder of the tabs comes from the order in the .menu files -get_submenuitems = function (startdir) - local t = {} - local menuitems = get_menuitems(startdir) - - for k,v in pairs(menuitems) do - if (menuitems[k]["tab"] ~= "") then - if not (t[menuitems[k]["controller"]]) then t[menuitems[k]["controller"]] = {} end - table.insert (t[menuitems[k]["controller"]], {tab=menuitems[k]["tab"],action=menuitems[k]["action"]}) + if #item >= 1 then + result = {} + result.cat, result.cat_prio = parse_menu_entry(item[1]) + if (item[2]) then result.group, result.group_prio = parse_menu_entry(item[2]) end + if (item[3]) then result.tab = parse_menu_entry(item[3]) end + if (item[4]) then result.action = parse_menu_entry(item[4]) end end end + return result +end - return t +-- Function to compare priorities, missing priority moves to the front, same priority sorted alphabetically +local prio_compare = function(x,y) + if x.priority == y.priority then + if x.name < y.name then return true end + return false + end + if nil == x.priority then return true end + if nil == y.priority then return false end + if tonumber(x.priority) < tonumber(y.priority) then return true end + return false end -- returns a table of all the menu items found, sorted by priority --- Table format: prefix controller cat group tab action get_menuitems = function (startdir) - local t = {} - for k,v in pairs(get_candidates(startdir)) do - local prefix, controller = mvc.dirname(v), mvc.basename(v, ".menu") - -- open the thing, and parse the contents - local fh = io.open(startdir .. "/" .. v) - local prio = 10 - for x in fh:lines() do - local c = string.match(x, "^#") or string.match(x,"^$") - if c == nil then - local item = {} - for i in string.gmatch(x, "%S+") do - table.insert(item, i) + local cats = {} + local reversecats = {} + startdir = (string.gsub(startdir, "/$", "")) --remove trailing / + for k,filename in pairs(get_candidates(startdir)) do + local controller = mvc.basename(filename, ".menu") + local prefix = (string.gsub(mvc.dirname(filename), startdir, "")) + + -- open the menu file, and parse the contents + local handle = io.open(filename) + for x in handle:lines() do + local result = parse_menu_line(x) + if result then + for i = 1,1 do -- loop so break works + -- Add the category + if nil == reversecats[result.cat] then + table.insert ( cats, + { name=result.cat, + groups = {}, + reversegroups = {} } ) + reversecats[result.cat] = #cats + end + local cat = cats[reversecats[result.cat]] + cat.priority = cat.priority or result.cat_prio + -- Add the group + if nil == result.group then break end + if nil == cat.groups[cat.reversegroups[result.group]] then + table.insert ( cat.groups, + { name = result.group, + controller = controller, + prefix = prefix, + tabs = {} } ) + cat.reversegroups[result.group] = #cat.groups + end + local group = cat.groups[cat.reversegroups[result.group]] + group.priority = group.priority or result.group_prio + -- Add the tab + if nil == result.tab or nil == result.action then break end + local tab = { name = result.tab, action = result.action } + table.insert(group.tabs, tab) end - table.insert(t, { prefix=prefix, - controller=controller, - catprio="nan", - cat=item[1] or "", - groupprio="nan", - group=item[2] or "", - tabprio=tostring(prio), - tab=item[3] or "", - action=item[4] or "" }) - prio=prio+5 - end - end - fh:close() - end - -- Ok, we now have the raw menu table - -- now try to parse out numbers in front of any cat, group or tabs - for x in ipairs(t) do - local f = t[x] - if (string.match(f.cat, "^%d")) then - f.catprio, f.cat = string.match(f.cat, "(%d+)(.*)") - end - if (string.match(f.group, "^%d")) then - f.groupprio, f.group = string.match(f.group, "(%d+)(.*)") - end - if (string.match(f.tab, "^%d")) then - f.tabprio, f.tab = string.match(f.tab, "(%d+)(.*)") - end - end - - -- Convert underscores to spaces - for x in ipairs(t) do - t[x].cat = string.gsub(t[x].cat, "_", " ") - t[x].group = string.gsub(t[x].group, "_", " ") - t[x].tab = string.gsub(t[x].tab, "_", " ") - end - - -- Now alpha sort - table.sort(t, function(x,y) - return t_compare (x,y,{"cat", "catprio", "group", "groupprio", "tab", "tabprio"} ) - end) - - -- Fill in the priorities - local fill_prio = function (t, start, stop, col) - local prio = t[start][col] - if prio == "nan" then prio = "0" end - while start <= stop do - t[start][col] = prio - start = start + 1 - end - end - - --- Fill in the priorities --- Warning - UGLY code ahead. --- Basic rules, for each cat and group, if the prio is nan, then set it --- to the lowest value for that group or cat. - local k = 1 - while ( k <= table.maxn(t) ) do - local c = k - while ( c <= table.maxn(t) and t[c].cat == t[k].cat ) do - c=c+1 - end - c=c-1 -- back up one - we only want whats the same - fill_prio(t,k,c,"catprio") - -- from k,c is a mini table, do the same for groupprio - local g = k - while ( g <= c ) do - local h = g - while ( h <= c and t[h].group == t[g].group ) do - h=h+1 end - h=h-1 --- back up one (again) - fill_prio(t,g,h,"groupprio") - g=h+1 end - k = c + 1 + handle:close() end - - -- Now priority sort - table.sort(t, function(x,y) - return t_compare (x,y,{"catprio", "cat", "groupprio", "group", "tabprio", "tab"} ) - end) + -- Now that we have the entire menu, sort by priority + -- Categories first + table.sort(cats, prio_compare) - -- drop the priorities - they were internal - for k,v in ipairs(t) do - v.catprio = nil - v.groupprio = nil - v.tabprio = nil + -- Then groups + for x, cat in ipairs(cats) do + cat.reversegroups = nil -- don't need reverse table anymore + table.sort(cat.groups, prio_compare) end - return t + return cats end |