From 315a7804b9e96532c3ea8ea0812cf4de88fa063f Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 6 Jan 2020 12:01:51 +0000 Subject: [PATCH] Message dialogs improvements (macos). --- file_darwin.go | 13 ++++++++++++ internal/osa/osa_darwin.go | 22 ++++++++++--------- internal/osa/scripts/file.gots | 22 ++++++++----------- internal/osa/scripts/msg.gots | 30 ++++++++++++-------------- msg_darwin.go | 39 ++++++++++++++++++++++------------ msg_windows.go | 6 +++--- zenity.go | 12 +++++++++++ 7 files changed, 87 insertions(+), 57 deletions(-) diff --git a/file_darwin.go b/file_darwin.go index a8e89a8..75e0b4e 100644 --- a/file_darwin.go +++ b/file_darwin.go @@ -1,6 +1,7 @@ package zenity import ( + "os/exec" "strings" "github.com/ncruces/zenity/internal/osa" @@ -14,6 +15,9 @@ func SelectFile(options ...Option) (string, error) { Location: opts.filename, Type: appleFilters(opts.filters), }) + if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { + return "", nil + } if err != nil { return "", err } @@ -32,6 +36,9 @@ func SelectFileMutiple(options ...Option) ([]string, error) { Location: opts.filename, Type: appleFilters(opts.filters), }) + if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { + return nil, nil + } if err != nil { return nil, err } @@ -51,6 +58,9 @@ func SelectFileSave(options ...Option) (string, error) { Prompt: opts.title, Location: opts.filename, }) + if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { + return "", nil + } if err != nil { return "", err } @@ -67,6 +77,9 @@ func SelectDirectory(options ...Option) (string, error) { Prompt: opts.title, Location: opts.filename, }) + if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { + return "", nil + } if err != nil { return "", err } diff --git a/internal/osa/osa_darwin.go b/internal/osa/osa_darwin.go index b497663..e50def8 100644 --- a/internal/osa/osa_darwin.go +++ b/internal/osa/osa_darwin.go @@ -16,7 +16,7 @@ func Run(script string, data interface{}) ([]byte, error) { } res := buf.String() - res = res[len("")] + res = res[len("")] cmd := exec.Command("osascript", "-l", "JavaScript") cmd.Stdin = strings.NewReader(res) return cmd.Output() @@ -25,19 +25,21 @@ func Run(script string, data interface{}) ([]byte, error) { type File struct { Operation string Prompt string + Name string Location string Type []string Multiple bool + Separator rune } type Msg struct { - Dialog bool - Text string - Message string - As string - Title string - Icon string - Buttons []string - Cancel int - Default int + Operation string + Text string + Message string + As string + Title string + Icon string + Buttons []string + Cancel int + Default int } diff --git a/internal/osa/scripts/file.gots b/internal/osa/scripts/file.gots index acaf673..475067a 100644 --- a/internal/osa/scripts/file.gots +++ b/internal/osa/scripts/file.gots @@ -6,23 +6,19 @@ var opts = {} opts.withPrompt = {{.Prompt}} opts.multipleSelectionsAllowed = {{.Multiple}} -{{if .Location -}} - opts.defaultLocation = {{.Location}} -{{end -}} {{if .Type -}} opts.ofType = {{.Type}} {{end -}} +{{if .Name -}} + opts.defaultName = {{.Name}} +{{end -}} +{{if .Location -}} + opts.defaultLocation = {{.Location}} +{{end -}} -var res -try { - res = app[{{.Operation}}](opts) -} catch (e) { - if (e.errorNumber !== -128) throw e -} +var res = app[{{.Operation}}](opts) if (Array.isArray(res)) { - res.join('\0') -} else if (res != null) { - res.toString() + res.join(String.fromCodePoint({{.Separator}})) } else { - void 0 + res.toString() } \ No newline at end of file diff --git a/internal/osa/scripts/msg.gots b/internal/osa/scripts/msg.gots index ffea618..6ccdb6e 100644 --- a/internal/osa/scripts/msg.gots +++ b/internal/osa/scripts/msg.gots @@ -4,6 +4,18 @@ app.activate() var opts = {} +{{if .Message -}} + opts.message = {{.Message}} +{{end -}} +{{if .As -}} + opts.as = {{.As}} +{{end -}} +{{if .Title -}} + opts.withTitle = {{.Title}} +{{end -}} +{{if .Icon -}} + opts.withIcon = {{.Icon}} +{{end -}} {{if .Buttons -}} opts.buttons = {{.Buttons}} {{end -}} @@ -14,20 +26,4 @@ var opts = {} opts.cancelButton = {{.Cancel}} {{end -}} -{{if .Dialog -}} - {{if .Title -}} - opts.withTitle = {{.Title}} - {{end -}} - {{if .Icon -}} - opts.withIcon = {{.Icon}} - {{end -}} - app.displayDialog({{.Text}}, opts) -{{else -}} - {{if .As -}} - opts.as = {{.As}} - {{end -}} - {{if .Message -}} - opts.message = {{.Message}} - {{end -}} - app.displayAlert({{.Text}}, opts) -{{end -}} \ No newline at end of file +app[{{.Operation}}]({{.Text}}, opts).buttonReturned \ No newline at end of file diff --git a/msg_darwin.go b/msg_darwin.go index 251ca87..109ada7 100644 --- a/msg_darwin.go +++ b/msg_darwin.go @@ -22,16 +22,24 @@ func Warning(text string, options ...Option) (bool, error) { return message(3, text, options) } -func message(dialog int, text string, options []Option) (bool, error) { +func message(typ int, text string, options []Option) (bool, error) { opts := optsParse(options) - data := osa.Msg{ - Text: text, - Title: opts.title, - Dialog: opts.icon != 0 || dialog == 2, + dialog := opts.icon != 0 || typ == 2 + var op string + if dialog { + op = "displayDialog" + } else { + op = "displayAlert" } - if data.Dialog { + data := osa.Msg{ + Operation: op, + Text: text, + Title: opts.title, + } + + if dialog { switch opts.icon { case ErrorIcon: data.Icon = "stop" @@ -41,7 +49,7 @@ func message(dialog int, text string, options []Option) (bool, error) { data.Icon = "caution" } } else { - switch dialog { + switch typ { case 0: data.As = "critical" case 1: @@ -56,20 +64,20 @@ func message(dialog int, text string, options []Option) (bool, error) { } } - if dialog != 2 { - opts.cancel = "" - if data.Dialog { + if typ != 2 { + if dialog { opts.ok = "OK" } + opts.cancel = "" } - if opts.ok != "" || opts.cancel != "" || opts.extra != "" || true { + if opts.ok != "" || opts.cancel != "" || opts.extra != "" { if opts.ok == "" { opts.ok = "OK" } if opts.cancel == "" { opts.cancel = "Cancel" } - if dialog == 2 { + if typ == 2 { if opts.extra == "" { data.Buttons = []string{opts.cancel, opts.ok} data.Default = 2 @@ -93,17 +101,20 @@ func message(dialog int, text string, options []Option) (bool, error) { if data.Cancel != 0 { data.Default = data.Cancel } - if data.Dialog && data.Buttons == nil { + if dialog && data.Buttons == nil { data.Default = 1 } } - _, err := osa.Run("msg", data) + out, err := osa.Run("msg", data) if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { return false, nil } if err != nil { return false, err } + if len(out) > 0 && string(out[:len(out)-1]) == opts.extra { + return false, ErrExtraButton + } return true, err } diff --git a/msg_windows.go b/msg_windows.go index 87e94ce..eba781b 100644 --- a/msg_windows.go +++ b/msg_windows.go @@ -26,15 +26,15 @@ func Warning(text string, options ...Option) (bool, error) { return message(3, text, options) } -func message(dialog int, text string, options []Option) (bool, error) { +func message(typ int, text string, options []Option) (bool, error) { opts := optsParse(options) var flags, caption uintptr switch { - case dialog == 2 && opts.extra != "": + case typ == 2 && opts.extra != "": flags |= 0x3 // MB_YESNOCANCEL - case dialog == 2 || opts.extra != "": + case typ == 2 || opts.extra != "": flags |= 0x1 // MB_OKCANCEL } diff --git a/zenity.go b/zenity.go index 97a263e..73ecaf0 100644 --- a/zenity.go +++ b/zenity.go @@ -1,5 +1,17 @@ package zenity +// Errors + +type constError string + +func (e constError) Error() string { return string(e) } + +// Message errors + +const ErrExtraButton = constError("Extra button pressed.") + +// Options + type options struct { // General options title string