Convert wsl/cygwin paths (windows).
This commit is contained in:
parent
2d90a83943
commit
b5599a5bf3
6 changed files with 87 additions and 20 deletions
|
@ -3,6 +3,9 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/ncruces/zenity"
|
||||
|
@ -42,6 +45,10 @@ var (
|
|||
filename string
|
||||
separator string
|
||||
fileFilters FileFilters
|
||||
|
||||
// Windows specific options
|
||||
cygpath bool
|
||||
wslpath bool
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -64,11 +71,11 @@ func main() {
|
|||
case fileSelectionDlg:
|
||||
switch {
|
||||
default:
|
||||
strResult(zenity.SelectFile(opts...))
|
||||
strResult(egestPath(zenity.SelectFile(opts...)))
|
||||
case save:
|
||||
strResult(zenity.SelectFileSave(opts...))
|
||||
strResult(egestPath(zenity.SelectFileSave(opts...)))
|
||||
case multiple:
|
||||
lstResult(zenity.SelectFileMutiple(opts...))
|
||||
lstResult(egestPaths(zenity.SelectFileMutiple(opts...)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +118,12 @@ func setupFlags() {
|
|||
flag.StringVar(&filename, "filename", "", "Set the filename")
|
||||
flag.StringVar(&separator, "separator", "|", "Set output separator character")
|
||||
flag.Var(&fileFilters, "file-filter", "Set a filename filter (NAME | PATTERN1 PATTERN2 ...)")
|
||||
|
||||
// Windows specific options
|
||||
if runtime.GOOS == "windows" {
|
||||
flag.BoolVar(&cygpath, "cygpath", false, "Use cygpath for path translation (Windows only)")
|
||||
flag.BoolVar(&wslpath, "wslpath", false, "Use wslpath for path translation (Windows only)")
|
||||
}
|
||||
}
|
||||
|
||||
func validateFlags() {
|
||||
|
@ -174,7 +187,7 @@ func loadFlags() []zenity.Option {
|
|||
// File selection options
|
||||
|
||||
options = append(options, fileFilters.Build())
|
||||
options = append(options, zenity.Filename(filename))
|
||||
options = append(options, zenity.Filename(ingestPath(filename)))
|
||||
if directory {
|
||||
options = append(options, zenity.Directory())
|
||||
}
|
||||
|
@ -238,12 +251,66 @@ func lstResult(l []string, err error) {
|
|||
os.Exit(0)
|
||||
}
|
||||
|
||||
func ingestPath(path string) string {
|
||||
if runtime.GOOS == "windows" && path != "" {
|
||||
var args []string
|
||||
switch {
|
||||
case wslpath:
|
||||
args = []string{"wsl", "wslpath", "-m"}
|
||||
case cygpath:
|
||||
args = []string{"cygpath", "-C", "UTF8", "-m"}
|
||||
}
|
||||
if args != nil {
|
||||
args = append(args, path)
|
||||
out, err := exec.Command(args[0], args[1:]...).Output()
|
||||
if len(out) > 0 && err == nil {
|
||||
path = string(out[:len(out)-1])
|
||||
}
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func egestPath(path string, err error) (string, error) {
|
||||
if runtime.GOOS == "windows" && path != "" && err == nil {
|
||||
var args []string
|
||||
switch {
|
||||
case wslpath:
|
||||
args = []string{"wsl", "wslpath", "-u"}
|
||||
case cygpath:
|
||||
args = []string{"cygpath", "-C", "UTF8", "-u"}
|
||||
}
|
||||
if args != nil {
|
||||
var out []byte
|
||||
args = append(args, filepath.ToSlash(path))
|
||||
out, err = exec.Command(args[0], args[1:]...).Output()
|
||||
if len(out) > 0 && err == nil {
|
||||
path = string(out[:len(out)-1])
|
||||
}
|
||||
}
|
||||
}
|
||||
return path, err
|
||||
}
|
||||
|
||||
func egestPaths(paths []string, err error) ([]string, error) {
|
||||
if runtime.GOOS == "windows" && err == nil && (wslpath || cygpath) {
|
||||
paths = append(paths[:0:0], paths...)
|
||||
for i, p := range paths {
|
||||
paths[i], err = egestPath(p, nil)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return paths, err
|
||||
}
|
||||
|
||||
type FileFilters struct {
|
||||
zenity.FileFilters
|
||||
}
|
||||
|
||||
func (f *FileFilters) String() string {
|
||||
return "filename filter"
|
||||
return "zenity.FileFilters"
|
||||
}
|
||||
|
||||
func (f *FileFilters) Set(s string) error {
|
||||
|
|
|
@ -275,9 +275,9 @@ func browseForFolder(opts options) (string, []string, error) {
|
|||
if opts.filename != "" {
|
||||
ptr := syscall.StringToUTF16Ptr(opts.filename)
|
||||
args.LParam = uintptr(unsafe.Pointer(ptr))
|
||||
args.CallbackFunc = syscall.NewCallback(func(hwnd uintptr, msg uint32, lparam, data uintptr) uintptr {
|
||||
args.CallbackFunc = syscall.NewCallback(func(wnd uintptr, msg uint32, lparam, data uintptr) uintptr {
|
||||
if msg == 1 { // BFFM_INITIALIZED
|
||||
sendMessage.Call(hwnd, 1024+103 /* BFFM_SETSELECTIONW */, 1 /* TRUE */, data)
|
||||
sendMessage.Call(wnd, 1024+103 /* BFFM_SETSELECTIONW */, 1 /* TRUE */, data)
|
||||
}
|
||||
return 0
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ package zenity_test
|
|||
import "github.com/ncruces/zenity"
|
||||
|
||||
func ExampleError() {
|
||||
zenity.Error("An error has occured.",
|
||||
zenity.Error("An error has occurred.",
|
||||
zenity.Title("Error"),
|
||||
zenity.Icon(zenity.ErrorIcon))
|
||||
// Output:
|
||||
|
|
|
@ -93,15 +93,15 @@ func hookMessageLabels(typ int, opts options) (hook uintptr, err error) {
|
|||
hook, _, err = setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET
|
||||
syscall.NewCallback(func(code int, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr {
|
||||
if lparam.Message == 0x0110 { // WM_INITDIALOG
|
||||
name := [7]byte{}
|
||||
n, _, _ := getClassName.Call(lparam.HWnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if string(name[:n]) == "#32770" {
|
||||
enumChildWindows.Call(lparam.HWnd,
|
||||
syscall.NewCallback(func(hwnd, lparam uintptr) uintptr {
|
||||
name := [7]byte{}
|
||||
n, _, _ := getClassName.Call(hwnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if string(name[:n]) == "Button" {
|
||||
ctl, _, _ := getDlgCtrlID.Call(hwnd)
|
||||
name := [7]uint16{}
|
||||
getClassName.Call(lparam.Wnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if syscall.UTF16ToString(name[:]) == "#32770" { // The class for a dialog box
|
||||
enumChildWindows.Call(lparam.Wnd,
|
||||
syscall.NewCallback(func(wnd, lparam uintptr) uintptr {
|
||||
name := [7]uint16{}
|
||||
getClassName.Call(wnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if syscall.UTF16ToString(name[:]) == "Button" {
|
||||
ctl, _, _ := getDlgCtrlID.Call(wnd)
|
||||
var text string
|
||||
switch ctl {
|
||||
case 1, 6: // IDOK, IDYES
|
||||
|
@ -119,7 +119,7 @@ func hookMessageLabels(typ int, opts options) (hook uintptr, err error) {
|
|||
}
|
||||
if text != "" {
|
||||
ptr := syscall.StringToUTF16Ptr(text)
|
||||
setWindowText.Call(hwnd, uintptr(unsafe.Pointer(ptr)))
|
||||
setWindowText.Call(wnd, uintptr(unsafe.Pointer(ptr)))
|
||||
}
|
||||
}
|
||||
return 1
|
||||
|
|
|
@ -23,7 +23,7 @@ var (
|
|||
coTaskMemFree = ole32.NewProc("CoTaskMemFree")
|
||||
|
||||
sendMessage = user32.NewProc("SendMessageW")
|
||||
getClassName = user32.NewProc("GetClassNameA")
|
||||
getClassName = user32.NewProc("GetClassNameW")
|
||||
setWindowsHookEx = user32.NewProc("SetWindowsHookExW")
|
||||
unhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
|
||||
callNextHookEx = user32.NewProc("CallNextHookEx")
|
||||
|
@ -46,7 +46,7 @@ type _CWPRETSTRUCT struct {
|
|||
LParam uintptr
|
||||
WParam uintptr
|
||||
Message uint32
|
||||
HWnd uintptr
|
||||
Wnd uintptr
|
||||
}
|
||||
|
||||
type _COMObject struct{}
|
Loading…
Reference in a new issue