You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.9 KiB
154 lines
4.9 KiB
-- see copyright notice in wxLdb.lua |
|
|
|
local print = print |
|
local wx = require( "wx" ) |
|
_G.print = print -- override wx print function with original one |
|
local mainthread = require( "mainthread" ) |
|
local utilities = require( "grldc.utilities" ) |
|
|
|
local setmetatable = setmetatable |
|
local assert = assert |
|
local coroutine = coroutine |
|
local debug = debug |
|
local error = error |
|
local string = string |
|
|
|
module( "ui.promptMountPath" ) |
|
|
|
local meta = { __index = {} } |
|
|
|
local function checkPath( user, auto ) |
|
if auto == nil then return true end |
|
if string.sub( auto, 1, #user ) ~= user then |
|
wx.wxMessageBox( "Bad path: "..user.." not prefix of "..auto, "Error" ) |
|
return false |
|
end |
|
local s = string.sub( auto, #user, #user ) |
|
if s ~= "/" and s ~= "\\" then |
|
--print( user.." does not finish with /" ) |
|
s = string.sub( auto, #user+1, #user+1 ) |
|
end |
|
if s ~= "/" and s ~= "\\" and s ~= "" then |
|
wx.wxMessageBox( "Bad path: "..user.." does not finish with / and is not a parent directory of "..auto, "Error" ) |
|
return false |
|
end |
|
return true |
|
end |
|
|
|
function new() |
|
local self = {} |
|
setmetatable( self, meta ) |
|
self:initLayout_() |
|
return self |
|
end |
|
|
|
function meta.__index:destroy() |
|
self.dialog:Destroy() |
|
end |
|
|
|
function meta.__index:run( remotePath, localPath, fileName ) |
|
if remotePath ~= nil and localPath == nil and fileName ~= nil then |
|
-- we can use the file open dialog to select the local file |
|
local fullPath = nil |
|
local fileDialog = wx.wxFileDialog( wx.NULL, "Find source file: "..remotePath..fileName, "", fileName, "Lua files (*.lua)|*.lua|Text files (*.txt)|*.txt|All files (*)|*", wx.wxOPEN + wx.wxFILE_MUST_EXIST ) |
|
if fileDialog:ShowModal() == wx.wxID_OK then |
|
fullPath = fileDialog:GetPath() |
|
end |
|
fileDialog:Destroy() |
|
|
|
if fullPath == nil then return nil end |
|
|
|
fullPath = utilities.normalizePath( fullPath ) |
|
|
|
if string.sub( fullPath, -#fileName-1 ) ~= "/"..fileName then |
|
wx.wxMessageBox( "Remote file and local file must have the same name", "Invalid local source file" ) |
|
return nil |
|
else |
|
local lPath = string.sub( fullPath, 1, -#fileName-2 ) |
|
local rPath = utilities.normalizePath( remotePath ) |
|
--[[while true do |
|
print( lPath, rPath ) |
|
local suffix |
|
_, _, suffix = string.find( lPath, ".*(/.+)$" ) |
|
if suffix == nil then break end |
|
if string.sub( rPath, -#suffix ) ~= suffix then break end |
|
lPath = string.sub( lPath, 1, -#suffix-1 ) |
|
rPath = string.sub( rPath, 1, -#suffix-1 ) |
|
end]] |
|
--return rPath, lPath |
|
localPath = lPath |
|
end |
|
end |
|
assert( self.waiting == nil ) |
|
self.waiting = coroutine.running() |
|
assert( self.waiting ~= nil ) |
|
|
|
self.mount:SetValue( remotePath or "" ) |
|
self.path:SetValue( localPath or "" ) |
|
self.dialog:Show( true ) |
|
local ok = coroutine.yield() |
|
assert( self.waiting == coroutine.running() ) |
|
self.waiting = nil |
|
self.dialog:Show( false ) |
|
if ok then |
|
local mount = self.mount:GetValue() |
|
local path = self.path:GetValue() |
|
if not checkPath( mount, remotePath ) or not checkPath( path, localPath ) then |
|
return self:run( remotePath, localPath ) |
|
end |
|
return mount, path |
|
else |
|
return nil |
|
end |
|
end |
|
|
|
function meta.__index:initLayout_() |
|
self.dialog = wx.wxDialog( wx.NULL, wx.wxID_ANY, "Unknown path", wx.wxDefaultPosition, wx.wxDefaultSize ) |
|
local panel = wx.wxPanel( self.dialog, wx.wxID_ANY ) |
|
local vSizer = wx.wxBoxSizer( wx.wxVERTICAL ) |
|
local sizer |
|
|
|
sizer = wx.wxBoxSizer( wx.wxHORIZONTAL ) |
|
local label = wx.wxStaticText( panel, wx.wxID_ANY, "Please map the following remote path, or a part of it, to the corresponding local path" ) |
|
sizer:Add( label ) |
|
vSizer:Add( sizer ) |
|
|
|
sizer = wx.wxBoxSizer( wx.wxHORIZONTAL ) |
|
label = wx.wxStaticText( panel, wx.wxID_ANY, "remote path" ) |
|
sizer:Add( label ) |
|
self.mount = wx.wxTextCtrl( panel, wx.wxID_ANY ) |
|
sizer:Add( self.mount ) |
|
vSizer:Add( sizer ) |
|
|
|
sizer = wx.wxBoxSizer( wx.wxHORIZONTAL ) |
|
label = wx.wxStaticText( panel, wx.wxID_ANY, "local path" ) |
|
sizer:Add( label ) |
|
self.path = wx.wxTextCtrl( panel, wx.wxID_ANY ) |
|
sizer:Add( self.path ) |
|
vSizer:Add( sizer ) |
|
|
|
sizer = wx.wxBoxSizer( wx.wxHORIZONTAL ) |
|
local ok = wx.wxButton( panel, wx.wxID_ANY, "OK" ) |
|
mainthread.execute( function() |
|
self.dialog:Connect( ok:GetId(), wx.wxEVT_COMMAND_BUTTON_CLICKED, function() self:onEnd_( true ) end ) |
|
end ) |
|
sizer:Add( ok ) |
|
local cancel = wx.wxButton( panel, wx.wxID_ANY, "Cancel" ) |
|
mainthread.execute( function() |
|
self.dialog:Connect( cancel:GetId(), wx.wxEVT_COMMAND_BUTTON_CLICKED, function() self:onEnd_( false ) end ) |
|
end ) |
|
sizer:Add( cancel ) |
|
vSizer:Add( sizer ) |
|
|
|
panel:SetSizer( vSizer ) |
|
vSizer:SetSizeHints( self.dialog ) |
|
|
|
mainthread.execute( function() |
|
self.dialog:Connect( wx.wxEVT_CLOSE_WINDOW, function() self:onEnd_( false ) end ) |
|
end ) |
|
end |
|
|
|
function meta.__index:onEnd_( ok ) |
|
local status, msg = coroutine.resume( self.waiting, ok ) |
|
assert( status, debug.traceback( self.waiting, msg ) ) |
|
end
|
|
|