diff --git a/cmd/zenity/.gitignore b/cmd/zenity/.gitignore index 99f8ec0..afc690a 100644 --- a/cmd/zenity/.gitignore +++ b/cmd/zenity/.gitignore @@ -1 +1,2 @@ zenity +*.syso \ No newline at end of file diff --git a/cmd/zenity/main.go b/cmd/zenity/main.go index 29040ed..7ce1557 100644 --- a/cmd/zenity/main.go +++ b/cmd/zenity/main.go @@ -11,6 +11,8 @@ import ( "github.com/ncruces/zenity/internal/cmd" ) +//go:generate go run github.com/josephspurrier/goversioninfo/cmd/goversioninfo -platform-specific -manifest=win.manifest + var ( // Application Options errorDlg bool @@ -58,6 +60,18 @@ func main() { msgResult(zenity.Warning(text, opts...)) case questionDlg: msgResult(zenity.Question(text, opts...)) + + case fileSelectionDlg: + switch { + default: + strResult(zenity.SelectFile(opts...)) + case save: + strResult(zenity.SelectFileSave(opts...)) + case directory: + strResult(zenity.SelectDirectory(opts...)) + case multiple: + lstResult(zenity.SelectFileMutiple(opts...)) + } } flag.Usage() @@ -95,7 +109,7 @@ func setupFlags() { flag.BoolVar(&directory, "directory", false, "Activate directory-only selection") flag.BoolVar(&confirmOverwrite, "confirm-overwrite", false, "Confirm file selection if filename already exists") flag.StringVar(&filename, "filename", "", "Set the filename") - flag.StringVar(&separator, "separator", "", "Set output separator character") + flag.StringVar(&separator, "separator", "|", "Set output separator character") flag.Var(&fileFilters, "file-filter", "Set a filename filter (NAME | PATTERN1 PATTERN2 ...)") } @@ -157,6 +171,16 @@ func loadFlags() []zenity.Option { options = append(options, zenity.DefaultCancel) } + // File selection options + + options = append(options, fileFilters.New()) + options = append(options, zenity.Filename(filename)) + if confirmOverwrite { + options = append(options, zenity.ConfirmOverwrite) + } + + cmd.Separator = separator + return options } @@ -177,8 +201,36 @@ func msgResult(ok bool, err error) { os.Exit(1) } +func strResult(s string, err error) { + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Stderr.WriteString(cmd.LineBreak) + os.Exit(-1) + } + if s == "" { + os.Exit(1) + } + os.Stdout.WriteString(s) + os.Stdout.WriteString(cmd.LineBreak) + os.Exit(0) +} + +func lstResult(l []string, err error) { + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Stderr.WriteString(cmd.LineBreak) + os.Exit(-1) + } + os.Stdout.WriteString(strings.Join(l, separator)) + os.Stdout.WriteString(cmd.LineBreak) + if l == nil { + os.Exit(1) + } + os.Exit(0) +} + type FileFilters struct { - list []zenity.FileFilter + zenity.FileFilters } func (f *FileFilters) String() string { @@ -193,8 +245,8 @@ func (f *FileFilters) Set(s string) error { s = split[1] } - filter.Exts = strings.Split(s, " ") - f.list = append(f.list, filter) + filter.Patterns = strings.Split(s, " ") + f.FileFilters = append(f.FileFilters, filter) return nil } diff --git a/cmd/zenity/versioninfo.json b/cmd/zenity/versioninfo.json new file mode 100644 index 0000000..5558768 --- /dev/null +++ b/cmd/zenity/versioninfo.json @@ -0,0 +1,41 @@ +{ + "FixedFileInfo": { + "FileVersion": { + "Major": 0, + "Minor": 0, + "Patch": 0, + "Build": 0 + }, + "ProductVersion": { + "Major": 0, + "Minor": 0, + "Patch": 0, + "Build": 0 + }, + "FileFlagsMask": "3f", + "FileFlags ": "00", + "FileOS": "040004", + "FileType": "01", + "FileSubType": "00" + }, + "StringFileInfo": { + "Comments": "zenity", + "CompanyName": "Nuno Cruces", + "FileDescription": "", + "FileVersion": "0.0.0.0", + "InternalName": "zenity", + "LegalCopyright": "© 2020 Nuno Cruces", + "LegalTrademarks": "", + "OriginalFilename": "zenity.exe", + "PrivateBuild": "", + "ProductName": "zenity", + "ProductVersion": "0.0.0", + "SpecialBuild": "" + }, + "VarFileInfo": { + "Translation": { + "LangID": "0409", + "CharsetID": "04B0" + } + } +} \ No newline at end of file diff --git a/cmd/zenity/win.manifest b/cmd/zenity/win.manifest new file mode 100644 index 0000000..3de7837 --- /dev/null +++ b/cmd/zenity/win.manifest @@ -0,0 +1,9 @@ + + + + + true/pm + PerMonitorV2, PerMonitor + + + \ No newline at end of file diff --git a/file_darwin.go b/file_darwin.go index 75e0b4e..c4850af 100644 --- a/file_darwin.go +++ b/file_darwin.go @@ -92,8 +92,8 @@ func SelectDirectory(options ...Option) (string, error) { func appleFilters(filters []FileFilter) []string { var filter []string for _, f := range filters { - for _, e := range f.Exts { - filter = append(filter, strings.TrimPrefix(e, ".")) + for _, p := range f.Patterns { + filter = append(filter, p) // FIXME } } return filter diff --git a/file_test.go b/file_test.go index d5996b9..4797ad0 100644 --- a/file_test.go +++ b/file_test.go @@ -6,9 +6,9 @@ const defaultPath = "" func TestSelectFile(t *testing.T) { res, err := SelectFile(Filename(defaultPath), FileFilters{ - {"Go files", []string{".go"}}, - {"Web files", []string{".html", ".js", ".css"}}, - {"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}}, + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, }.New()) if err != nil { @@ -20,9 +20,9 @@ func TestSelectFile(t *testing.T) { func TestSelectFileMutiple(t *testing.T) { res, err := SelectFileMutiple(Filename(defaultPath), FileFilters{ - {"Go files", []string{".go"}}, - {"Web files", []string{".html", ".js", ".css"}}, - {"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}}, + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, }.New()) if err != nil { @@ -34,9 +34,9 @@ func TestSelectFileMutiple(t *testing.T) { func TestSelectFileSave(t *testing.T) { res, err := SelectFileSave(Filename(defaultPath), ConfirmOverwrite, FileFilters{ - {"Go files", []string{".go"}}, - {"Web files", []string{".html", ".js", ".css"}}, - {"Image files", []string{".png", ".gif", ".ico", ".jpg", ".webp"}}, + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, }.New()) if err != nil { diff --git a/file_unix.go b/file_unix.go index 33b851b..f72fbde 100644 --- a/file_unix.go +++ b/file_unix.go @@ -118,9 +118,8 @@ func zenityFilters(filters []FileFilter) []string { buf.WriteString(f.Name) buf.WriteRune('|') } - for _, e := range f.Exts { - buf.WriteRune('*') - buf.WriteString(e) + for _, p := range f.Patterns { + buf.WriteString(p) buf.WriteRune(' ') } res = append(res, buf.String()) diff --git a/file_windows.go b/file_windows.go index 98113b2..63fd5b1 100644 --- a/file_windows.go +++ b/file_windows.go @@ -31,7 +31,9 @@ func SelectFile(options ...Option) (string, error) { if opts.filename != "" { args.InitialDir = syscall.StringToUTF16Ptr(opts.filename) } - args.Filter = &windowsFilters(opts.filters)[0] + if opts.filters != nil { + args.Filter = &windowsFilters(opts.filters)[0] + } res := [32768]uint16{} args.File = &res[0] @@ -59,7 +61,9 @@ func SelectFileMutiple(options ...Option) ([]string, error) { if opts.filename != "" { args.InitialDir = syscall.StringToUTF16Ptr(opts.filename) } - args.Filter = &windowsFilters(opts.filters)[0] + if opts.filters != nil { + args.Filter = &windowsFilters(opts.filters)[0] + } res := [32768 + 1024*256]uint16{} args.File = &res[0] @@ -115,7 +119,9 @@ func SelectFileSave(options ...Option) (string, error) { if opts.overwrite { args.Flags |= 0x2 // OFN_OVERWRITEPROMPT } - args.Filter = &windowsFilters(opts.filters)[0] + if opts.filters != nil { + args.Filter = &windowsFilters(opts.filters)[0] + } res := [32768]uint16{} args.File = &res[0] @@ -236,9 +242,8 @@ func windowsFilters(filters []FileFilter) []uint16 { for _, f := range filters { res = append(res, utf16.Encode([]rune(f.Name))...) res = append(res, 0) - for _, e := range f.Exts { - res = append(res, uint16('*')) - res = append(res, utf16.Encode([]rune(e))...) + for _, p := range f.Patterns { + res = append(res, utf16.Encode([]rune(p))...) res = append(res, uint16(';')) } res = append(res, 0) diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 5d580ed..f4809e9 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -1,3 +1,4 @@ package cmd var Command bool +var Separator string diff --git a/internal/osa/osa.go b/internal/osa/osa.go index 0760856..5c41bc8 100644 --- a/internal/osa/osa.go +++ b/internal/osa/osa.go @@ -1 +1,3 @@ package osa + +//go:generate go run scripts/generate.go scripts/ diff --git a/internal/osa/osa_darwin.go b/internal/osa/osa_darwin.go index 4938611..4ec8240 100644 --- a/internal/osa/osa_darwin.go +++ b/internal/osa/osa_darwin.go @@ -9,8 +9,6 @@ import ( "github.com/ncruces/zenity/internal/cmd" ) -//go:generate go run scripts/generate.go scripts/ - func Run(script string, data interface{}) ([]byte, error) { var buf strings.Builder diff --git a/msg_windows.go b/msg_windows.go index 3a93753..87da2f4 100644 --- a/msg_windows.go +++ b/msg_windows.go @@ -91,13 +91,12 @@ func message(typ int, text string, options []Option) (bool, error) { func hookMessageLabels(typ int, opts options) (hook uintptr, err error) { tid, _, _ := getCurrentThreadId.Call() hook, _, err = setWindowsHookEx.Call(12, // WH_CALLWNDPROCRET - syscall.NewCallback(func(code int, wparam, lparam uintptr) uintptr { - msg := *(*_CWPRETSTRUCT)(unsafe.Pointer(lparam)) - if msg.Message == 0x0110 { // WM_INITDIALOG + syscall.NewCallback(func(code int, wparam uintptr, lparam *_CWPRETSTRUCT) uintptr { + if lparam.Message == 0x0110 { // WM_INITDIALOG name := [7]byte{} - n, _, _ := getClassName.Call(msg.HWnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name))) + n, _, _ := getClassName.Call(lparam.HWnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name))) if string(name[:n]) == "#32770" { - enumChildWindows.Call(msg.HWnd, + 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))) @@ -127,7 +126,7 @@ func hookMessageLabels(typ int, opts options) (hook uintptr, err error) { }), 0) } } - next, _, _ := callNextHookEx.Call(hook, uintptr(code), wparam, lparam) + next, _, _ := callNextHookEx.Call(hook, uintptr(code), wparam, uintptr(unsafe.Pointer(lparam))) return next }), 0, tid) return diff --git a/zenity.go b/zenity.go index 73ecaf0..263ef77 100644 --- a/zenity.go +++ b/zenity.go @@ -61,8 +61,8 @@ func ConfirmOverwrite(o *options) { } type FileFilter struct { - Name string - Exts []string + Name string + Patterns []string } type FileFilters []FileFilter