Message dialogs improvements (macos).
This commit is contained in:
parent
1824aab27c
commit
315a7804b9
7 changed files with 87 additions and 57 deletions
|
@ -1,6 +1,7 @@
|
||||||
package zenity
|
package zenity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ncruces/zenity/internal/osa"
|
"github.com/ncruces/zenity/internal/osa"
|
||||||
|
@ -14,6 +15,9 @@ func SelectFile(options ...Option) (string, error) {
|
||||||
Location: opts.filename,
|
Location: opts.filename,
|
||||||
Type: appleFilters(opts.filters),
|
Type: appleFilters(opts.filters),
|
||||||
})
|
})
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -32,6 +36,9 @@ func SelectFileMutiple(options ...Option) ([]string, error) {
|
||||||
Location: opts.filename,
|
Location: opts.filename,
|
||||||
Type: appleFilters(opts.filters),
|
Type: appleFilters(opts.filters),
|
||||||
})
|
})
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -51,6 +58,9 @@ func SelectFileSave(options ...Option) (string, error) {
|
||||||
Prompt: opts.title,
|
Prompt: opts.title,
|
||||||
Location: opts.filename,
|
Location: opts.filename,
|
||||||
})
|
})
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -67,6 +77,9 @@ func SelectDirectory(options ...Option) (string, error) {
|
||||||
Prompt: opts.title,
|
Prompt: opts.title,
|
||||||
Location: opts.filename,
|
Location: opts.filename,
|
||||||
})
|
})
|
||||||
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func Run(script string, data interface{}) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res := buf.String()
|
res := buf.String()
|
||||||
res = res[len("<script>") : len(res)-len("</script>")]
|
res = res[len("<script>") : len(res)-len("\n</script>")]
|
||||||
cmd := exec.Command("osascript", "-l", "JavaScript")
|
cmd := exec.Command("osascript", "-l", "JavaScript")
|
||||||
cmd.Stdin = strings.NewReader(res)
|
cmd.Stdin = strings.NewReader(res)
|
||||||
return cmd.Output()
|
return cmd.Output()
|
||||||
|
@ -25,19 +25,21 @@ func Run(script string, data interface{}) ([]byte, error) {
|
||||||
type File struct {
|
type File struct {
|
||||||
Operation string
|
Operation string
|
||||||
Prompt string
|
Prompt string
|
||||||
|
Name string
|
||||||
Location string
|
Location string
|
||||||
Type []string
|
Type []string
|
||||||
Multiple bool
|
Multiple bool
|
||||||
|
Separator rune
|
||||||
}
|
}
|
||||||
|
|
||||||
type Msg struct {
|
type Msg struct {
|
||||||
Dialog bool
|
Operation string
|
||||||
Text string
|
Text string
|
||||||
Message string
|
Message string
|
||||||
As string
|
As string
|
||||||
Title string
|
Title string
|
||||||
Icon string
|
Icon string
|
||||||
Buttons []string
|
Buttons []string
|
||||||
Cancel int
|
Cancel int
|
||||||
Default int
|
Default int
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,19 @@ var opts = {}
|
||||||
opts.withPrompt = {{.Prompt}}
|
opts.withPrompt = {{.Prompt}}
|
||||||
opts.multipleSelectionsAllowed = {{.Multiple}}
|
opts.multipleSelectionsAllowed = {{.Multiple}}
|
||||||
|
|
||||||
{{if .Location -}}
|
|
||||||
opts.defaultLocation = {{.Location}}
|
|
||||||
{{end -}}
|
|
||||||
{{if .Type -}}
|
{{if .Type -}}
|
||||||
opts.ofType = {{.Type}}
|
opts.ofType = {{.Type}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
{{if .Name -}}
|
||||||
|
opts.defaultName = {{.Name}}
|
||||||
|
{{end -}}
|
||||||
|
{{if .Location -}}
|
||||||
|
opts.defaultLocation = {{.Location}}
|
||||||
|
{{end -}}
|
||||||
|
|
||||||
var res
|
var res = app[{{.Operation}}](opts)
|
||||||
try {
|
|
||||||
res = app[{{.Operation}}](opts)
|
|
||||||
} catch (e) {
|
|
||||||
if (e.errorNumber !== -128) throw e
|
|
||||||
}
|
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
res.join('\0')
|
res.join(String.fromCodePoint({{.Separator}}))
|
||||||
} else if (res != null) {
|
|
||||||
res.toString()
|
|
||||||
} else {
|
} else {
|
||||||
void 0
|
res.toString()
|
||||||
}
|
}
|
|
@ -4,6 +4,18 @@ app.activate()
|
||||||
|
|
||||||
var opts = {}
|
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 -}}
|
{{if .Buttons -}}
|
||||||
opts.buttons = {{.Buttons}}
|
opts.buttons = {{.Buttons}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
@ -14,20 +26,4 @@ var opts = {}
|
||||||
opts.cancelButton = {{.Cancel}}
|
opts.cancelButton = {{.Cancel}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
||||||
{{if .Dialog -}}
|
app[{{.Operation}}]({{.Text}}, opts).buttonReturned
|
||||||
{{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 -}}
|
|
|
@ -22,16 +22,24 @@ func Warning(text string, options ...Option) (bool, error) {
|
||||||
return message(3, text, options)
|
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)
|
opts := optsParse(options)
|
||||||
|
|
||||||
data := osa.Msg{
|
dialog := opts.icon != 0 || typ == 2
|
||||||
Text: text,
|
var op string
|
||||||
Title: opts.title,
|
if dialog {
|
||||||
Dialog: opts.icon != 0 || dialog == 2,
|
op = "displayDialog"
|
||||||
|
} else {
|
||||||
|
op = "displayAlert"
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.Dialog {
|
data := osa.Msg{
|
||||||
|
Operation: op,
|
||||||
|
Text: text,
|
||||||
|
Title: opts.title,
|
||||||
|
}
|
||||||
|
|
||||||
|
if dialog {
|
||||||
switch opts.icon {
|
switch opts.icon {
|
||||||
case ErrorIcon:
|
case ErrorIcon:
|
||||||
data.Icon = "stop"
|
data.Icon = "stop"
|
||||||
|
@ -41,7 +49,7 @@ func message(dialog int, text string, options []Option) (bool, error) {
|
||||||
data.Icon = "caution"
|
data.Icon = "caution"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch dialog {
|
switch typ {
|
||||||
case 0:
|
case 0:
|
||||||
data.As = "critical"
|
data.As = "critical"
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -56,20 +64,20 @@ func message(dialog int, text string, options []Option) (bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dialog != 2 {
|
if typ != 2 {
|
||||||
opts.cancel = ""
|
if dialog {
|
||||||
if data.Dialog {
|
|
||||||
opts.ok = "OK"
|
opts.ok = "OK"
|
||||||
}
|
}
|
||||||
|
opts.cancel = ""
|
||||||
}
|
}
|
||||||
if opts.ok != "" || opts.cancel != "" || opts.extra != "" || true {
|
if opts.ok != "" || opts.cancel != "" || opts.extra != "" {
|
||||||
if opts.ok == "" {
|
if opts.ok == "" {
|
||||||
opts.ok = "OK"
|
opts.ok = "OK"
|
||||||
}
|
}
|
||||||
if opts.cancel == "" {
|
if opts.cancel == "" {
|
||||||
opts.cancel = "Cancel"
|
opts.cancel = "Cancel"
|
||||||
}
|
}
|
||||||
if dialog == 2 {
|
if typ == 2 {
|
||||||
if opts.extra == "" {
|
if opts.extra == "" {
|
||||||
data.Buttons = []string{opts.cancel, opts.ok}
|
data.Buttons = []string{opts.cancel, opts.ok}
|
||||||
data.Default = 2
|
data.Default = 2
|
||||||
|
@ -93,17 +101,20 @@ func message(dialog int, text string, options []Option) (bool, error) {
|
||||||
if data.Cancel != 0 {
|
if data.Cancel != 0 {
|
||||||
data.Default = data.Cancel
|
data.Default = data.Cancel
|
||||||
}
|
}
|
||||||
if data.Dialog && data.Buttons == nil {
|
if dialog && data.Buttons == nil {
|
||||||
data.Default = 1
|
data.Default = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := osa.Run("msg", data)
|
out, err := osa.Run("msg", data)
|
||||||
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
if len(out) > 0 && string(out[:len(out)-1]) == opts.extra {
|
||||||
|
return false, ErrExtraButton
|
||||||
|
}
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,15 @@ func Warning(text string, options ...Option) (bool, error) {
|
||||||
return message(3, text, options)
|
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)
|
opts := optsParse(options)
|
||||||
|
|
||||||
var flags, caption uintptr
|
var flags, caption uintptr
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case dialog == 2 && opts.extra != "":
|
case typ == 2 && opts.extra != "":
|
||||||
flags |= 0x3 // MB_YESNOCANCEL
|
flags |= 0x3 // MB_YESNOCANCEL
|
||||||
case dialog == 2 || opts.extra != "":
|
case typ == 2 || opts.extra != "":
|
||||||
flags |= 0x1 // MB_OKCANCEL
|
flags |= 0x1 // MB_OKCANCEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
zenity.go
12
zenity.go
|
@ -1,5 +1,17 @@
|
||||||
package zenity
|
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 {
|
type options struct {
|
||||||
// General options
|
// General options
|
||||||
title string
|
title string
|
||||||
|
|
Loading…
Reference in a new issue