mirror of
https://github.com/20kdc/OC-KittenOS.git
synced 2024-11-27 04:48:05 +11:00
dcd7154ec2
This license change should only increase the amount of stuff people can do in countries where the public domain is not a valid concept. If this license somehow restricts you as opposed to the previous one, please file an issue.
221 lines
6.3 KiB
Lua
221 lines
6.3 KiB
Lua
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
|
|
--
|
|
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
|
--
|
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
-- THIS SOFTWARE.
|
|
|
|
-- Used by filedialog to provide a sane relative environment.
|
|
-- Essentially, the filedialog is just a 'thin' UI wrapper over this.
|
|
-- Returns the root node.
|
|
|
|
local function dialog(name, parent)
|
|
return {
|
|
name = name,
|
|
list = function () return {{"Back", function () return nil, parent end}} end,
|
|
unknownAvailable = false,
|
|
selectUnknown = function (text) end
|
|
}
|
|
end
|
|
|
|
local getFsNode, getRoot
|
|
local setupCopyNode
|
|
function setupCopyNode(parent, myRoot, op, complete)
|
|
local function handleResult(aRes, res)
|
|
if aRes then
|
|
return complete(res, true)
|
|
else
|
|
return nil, setupCopyNode(parent, res, op, complete)
|
|
end
|
|
end
|
|
return {
|
|
name = "(" .. op .. ") " .. myRoot.name,
|
|
list = function ()
|
|
local l = {}
|
|
table.insert(l, {"Cancel Operation: " .. op, function ()
|
|
complete(nil, false)
|
|
return false, parent
|
|
end})
|
|
for _, v in ipairs(myRoot.list()) do
|
|
table.insert(l, {v[1], function ()
|
|
return handleResult(v[2]())
|
|
end})
|
|
end
|
|
return l
|
|
end,
|
|
unknownAvailable = myRoot.unknownAvailable,
|
|
selectUnknown = function (tx)
|
|
return handleResult(myRoot.selectUnknown(tx))
|
|
end
|
|
}
|
|
end
|
|
local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
|
|
if not fwrap then
|
|
return false, dialog("Could not open source", parent)
|
|
end
|
|
local myRoot = getRoot(fs, true, impliedName)
|
|
-- Setup wrapping node
|
|
return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent)
|
|
if not fwrap2 then
|
|
fwrap.close()
|
|
if intent then
|
|
return false, dialog("Could not open dest.", parent)
|
|
end
|
|
return false, parent
|
|
end
|
|
local data = fwrap.read(neo.readBufSize)
|
|
while data do
|
|
fwrap2.write(data)
|
|
data = fwrap.read(neo.readBufSize)
|
|
end
|
|
fwrap.close()
|
|
fwrap2.close()
|
|
return false, dialog("Completed copy.", parent)
|
|
end)
|
|
end
|
|
function getFsNode(fs, parent, fsc, path, mode, impliedName)
|
|
local va = fsc.address:sub(1, 4)
|
|
local fscrw = not fsc.isReadOnly()
|
|
local dir = path:sub(#path, #path) == "/"
|
|
local confirmedDel = false
|
|
local t
|
|
local function selectUnknown(text)
|
|
-- Relies on text being nil if used in leaf node
|
|
local rt, re = require("sys-filewrap").create(fsc, path .. (text or ""), mode)
|
|
if not rt then
|
|
return false, dialog("Open Error: " .. tostring(re), parent)
|
|
end
|
|
return true, rt
|
|
end
|
|
t = {
|
|
name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
|
|
list = function ()
|
|
local n = {}
|
|
n[1] = {"..", function ()
|
|
return nil, parent
|
|
end}
|
|
if dir then
|
|
for k, v in ipairs(fsc.list(path)) do
|
|
local nm = "F: " .. v
|
|
local fp = path .. v
|
|
local cDir = fsc.isDirectory(fp)
|
|
if cDir then
|
|
nm = "D: " .. v
|
|
end
|
|
if (not cDir) and (fscrw or mode == false) and (mode ~= nil) then
|
|
local vn = v
|
|
n[k + 1] = {nm, function () return selectUnknown(vn) end}
|
|
else
|
|
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode, impliedName) end}
|
|
end
|
|
end
|
|
else
|
|
table.insert(n, {"Copy", function ()
|
|
local rt, re = require("sys-filewrap").create(fsc, path, false)
|
|
if not rt then
|
|
return false, dialog("Open Error: " .. tostring(re), parent)
|
|
end
|
|
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
|
|
end})
|
|
end
|
|
if fscrw then
|
|
if dir then
|
|
table.insert(n, {"Mk. Directory", function ()
|
|
return nil, {
|
|
name = "MKDIR...",
|
|
list = function () return {{
|
|
"Cancel", function ()
|
|
return false, t
|
|
end
|
|
}} end,
|
|
unknownAvailable = true,
|
|
selectUnknown = function (text)
|
|
fsc.makeDirectory(path .. text)
|
|
return nil, dialog("Done!", t)
|
|
end
|
|
}
|
|
end})
|
|
end
|
|
if path ~= "/" then
|
|
local delText = "Delete"
|
|
if confirmedDel then
|
|
delText = "Delete <ARMED>"
|
|
end
|
|
table.insert(n, {delText, function ()
|
|
if not confirmedDel then
|
|
confirmedDel = true
|
|
return nil, t
|
|
end
|
|
fsc.remove(path)
|
|
return nil, dialog("Done.", parent)
|
|
end})
|
|
else
|
|
table.insert(n, {"Relabel Disk", function ()
|
|
return nil, {
|
|
name = "Disk Relabel...",
|
|
list = function () return {{
|
|
fsc.getLabel() or "Cancel",
|
|
function ()
|
|
return false, t
|
|
end
|
|
}} end,
|
|
unknownAvailable = true,
|
|
selectUnknown = function (tx)
|
|
fsc.setLabel(tx)
|
|
return false, t
|
|
end
|
|
}
|
|
end})
|
|
end
|
|
end
|
|
if not dir then
|
|
elseif impliedName then
|
|
table.insert(n, {"Implied: " .. impliedName, function ()
|
|
return selectUnknown(impliedName)
|
|
end})
|
|
end
|
|
return n
|
|
end,
|
|
unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
|
|
selectUnknown = selectUnknown
|
|
}
|
|
return t
|
|
end
|
|
function getRoot(fs, mode, defName)
|
|
local t
|
|
t = {
|
|
name = "DRVS:",
|
|
list = function ()
|
|
local l = {}
|
|
for fsi in fs.list() do
|
|
local id = fsi.getLabel()
|
|
if fsi == fs.primary then
|
|
id = "NEO" .. ((id and (":" .. id)) or " Disk")
|
|
elseif fsi == fs.temporary then
|
|
id = "RAM" .. ((id and (" " .. id)) or "Disk")
|
|
else
|
|
id = id or "Disk"
|
|
end
|
|
local used, total = fsi.spaceUsed(), fsi.spaceTotal()
|
|
local amount = string.format("%02i", math.ceil((used / total) * 100))
|
|
local mb = math.floor(total / (1024 * 1024))
|
|
if fsi.isReadOnly() then
|
|
id = "RO " .. amount .. "% " .. mb .. "M " .. id
|
|
else
|
|
id = "RW " .. amount .. "% " .. mb .. "M " .. id
|
|
end
|
|
table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function ()
|
|
return nil, getFsNode(fs, t, fsi, "/", mode, defName)
|
|
end})
|
|
end
|
|
return l
|
|
end,
|
|
unknownAvailable = false,
|
|
selectUnknown = function (text)
|
|
return false, dialog("Ow, that hurt...", t)
|
|
end
|
|
}
|
|
return t
|
|
end
|
|
return getRoot
|