List (unix), refactor.

This commit is contained in:
Nuno Cruces 2021-04-08 16:43:14 +01:00
parent e0c4c9a88c
commit 08ed75b4c5
14 changed files with 177 additions and 276 deletions

View file

@ -2,7 +2,6 @@ package zenity
import ( import (
"image/color" "image/color"
"os/exec"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -21,11 +20,9 @@ func selectColor(opts options) (color.Color, error) {
float32(g) / 0xffff, float32(g) / 0xffff,
float32(b) / 0xffff, float32(b) / 0xffff,
}) })
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, ok, err := strResult(opts, out, err)
return nil, nil if ok {
return zenutil.ParseColor(str), nil
} }
if err != nil {
return nil, err return nil, err
}
return zenutil.ParseColor(string(out)), nil
} }

View file

@ -4,7 +4,6 @@ package zenity
import ( import (
"image/color" "image/color"
"os/exec"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -12,9 +11,7 @@ import (
func selectColor(opts options) (color.Color, error) { func selectColor(opts options) (color.Color, error) {
args := []string{"--color-selection"} args := []string{"--color-selection"}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title)
}
if opts.color != nil { if opts.color != nil {
args = append(args, "--color", zenutil.UnparseColor(opts.color)) args = append(args, "--color", zenutil.UnparseColor(opts.color))
} }
@ -23,11 +20,9 @@ func selectColor(opts options) (color.Color, error) {
} }
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, ok, err := strResult(opts, out, err)
return nil, nil if ok {
return zenutil.ParseColor(str), nil
} }
if err != nil {
return nil, err return nil, err
}
return zenutil.ParseColor(string(out)), nil
} }

View file

@ -1,9 +1,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -19,22 +16,11 @@ func entry(text string, opts options) (string, bool, error) {
data.SetButtons(getButtons(true, true, opts)) data.SetButtons(getButtons(true, true, opts))
out, err := zenutil.Run(opts.ctx, "dialog", data) out, err := zenutil.Run(opts.ctx, "dialog", data)
out = bytes.TrimSuffix(out, []byte{'\n'}) return strResult(opts, out, err)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
if opts.extraButton != nil &&
*opts.extraButton == string(out) {
return "", false, ErrExtraButton
}
return "", false, nil
}
if err != nil {
return "", false, err
}
return string(out), true, nil
} }
func password(opts options) (string, string, bool, error) { func password(opts options) (string, string, bool, error) {
opts.hideText = true opts.hideText = true
pass, ok, err := entry("Password:", opts) str, ok, err := entry("Password:", opts)
return "", pass, ok, err return "", str, ok, err
} }

View file

@ -3,97 +3,42 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"strconv"
"strings" "strings"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
func entry(text string, opts options) (string, bool, error) { func entry(text string, opts options) (string, bool, error) {
args := []string{"--entry", "--text", text, "--entry-text", opts.entryText} args := []string{"--entry", "--text", text}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendButtons(args, opts)
} args = appendWidthHeight(args, opts)
if opts.width > 0 { args = appendIcon(args, opts)
args = append(args, "--width", strconv.FormatUint(uint64(opts.width), 10)) if opts.entryText != "" {
} args = append(args, "--entry-text", opts.entryText)
if opts.height > 0 {
args = append(args, "--height", strconv.FormatUint(uint64(opts.height), 10))
}
if opts.okLabel != nil {
args = append(args, "--ok-label", *opts.okLabel)
}
if opts.cancelLabel != nil {
args = append(args, "--cancel-label", *opts.cancelLabel)
}
if opts.extraButton != nil {
args = append(args, "--extra-button", *opts.extraButton)
} }
if opts.hideText { if opts.hideText {
args = append(args, "--hide-text") args = append(args, "--hide-text")
} }
switch opts.icon {
case ErrorIcon:
args = append(args, "--window-icon=error")
case WarningIcon:
args = append(args, "--window-icon=warning")
case InfoIcon:
args = append(args, "--window-icon=info")
case QuestionIcon:
args = append(args, "--window-icon=question")
}
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
out = bytes.TrimSuffix(out, []byte{'\n'}) return strResult(opts, out, err)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
if opts.extraButton != nil &&
*opts.extraButton == string(out) {
return "", false, ErrExtraButton
}
return "", false, nil
}
if err != nil {
return "", false, err
}
return string(out), true, nil
} }
func password(opts options) (string, string, bool, error) { func password(opts options) (string, string, bool, error) {
args := []string{"--password"} args := []string{"--password"}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendButtons(args, opts)
}
if opts.okLabel != nil {
args = append(args, "--ok-label", *opts.okLabel)
}
if opts.cancelLabel != nil {
args = append(args, "--cancel-label", *opts.cancelLabel)
}
if opts.extraButton != nil {
args = append(args, "--extra-button", *opts.extraButton)
}
if opts.username { if opts.username {
args = append(args, "--username") args = append(args, "--username")
} }
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
out = bytes.TrimSuffix(out, []byte{'\n'}) str, ok, err := strResult(opts, out, err)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { if ok && opts.username {
if opts.extraButton != nil &&
*opts.extraButton == string(out) {
return "", "", false, ErrExtraButton
}
return "", "", false, nil
}
if err != nil {
return "", "", false, err
}
if opts.username {
if split := strings.SplitN(string(out), "|", 2); len(split) == 2 { if split := strings.SplitN(string(out), "|", 2); len(split) == 2 {
return split[0], split[1], true, nil return split[0], split[1], true, nil
} }
} }
return "", string(out), true, nil return "", str, ok, err
} }

View file

@ -1,8 +1,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"strings" "strings"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
@ -22,13 +20,8 @@ func selectFile(opts options) (string, error) {
} }
out, err := zenutil.Run(opts.ctx, "file", data) out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, _, err := strResult(opts, out, err)
return "", nil return str, err
}
if err != nil {
return "", err
}
return string(bytes.TrimSuffix(out, []byte{'\n'})), nil
} }
func selectFileMutiple(opts options) ([]string, error) { func selectFileMutiple(opts options) ([]string, error) {
@ -47,17 +40,7 @@ func selectFileMutiple(opts options) ([]string, error) {
} }
out, err := zenutil.Run(opts.ctx, "file", data) out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { return lstResult(opts, out, err)
return nil, nil
}
if err != nil {
return nil, err
}
out = bytes.TrimSuffix(out, []byte{'\n'})
if len(out) == 0 {
return nil, nil
}
return strings.Split(string(out), zenutil.Separator), nil
} }
func selectFileSave(opts options) (string, error) { func selectFileSave(opts options) (string, error) {
@ -73,13 +56,8 @@ func selectFileSave(opts options) (string, error) {
} }
out, err := zenutil.Run(opts.ctx, "file", data) out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, _, err := strResult(opts, out, err)
return "", nil return str, err
}
if err != nil {
return "", err
}
return string(bytes.TrimSuffix(out, []byte{'\n'})), nil
} }
func initFilters(filters []FileFilter) []string { func initFilters(filters []FileFilter) []string {

View file

@ -3,8 +3,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"strings" "strings"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
@ -12,78 +10,31 @@ import (
func selectFile(opts options) (string, error) { func selectFile(opts options) (string, error) {
args := []string{"--file-selection"} args := []string{"--file-selection"}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendFileArgs(args, opts)
}
if opts.directory {
args = append(args, "--directory")
}
if opts.filename != "" {
args = append(args, "--filename", opts.filename)
}
args = append(args, initFilters(opts.fileFilters)...)
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, _, err := strResult(opts, out, err)
return "", nil return str, err
}
if err != nil {
return "", err
}
return string(bytes.TrimSuffix(out, []byte{'\n'})), nil
} }
func selectFileMutiple(opts options) ([]string, error) { func selectFileMutiple(opts options) ([]string, error) {
args := []string{"--file-selection", "--multiple", "--separator", zenutil.Separator} args := []string{"--file-selection", "--multiple", "--separator", zenutil.Separator}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendFileArgs(args, opts)
}
if opts.directory {
args = append(args, "--directory")
}
if opts.filename != "" {
args = append(args, "--filename", opts.filename)
}
args = append(args, initFilters(opts.fileFilters)...)
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { return lstResult(opts, out, err)
return nil, nil
}
if err != nil {
return nil, err
}
out = bytes.TrimSuffix(out, []byte{'\n'})
if len(out) == 0 {
return nil, nil
}
return strings.Split(string(out), zenutil.Separator), nil
} }
func selectFileSave(opts options) (string, error) { func selectFileSave(opts options) (string, error) {
args := []string{"--file-selection", "--save"} args := []string{"--file-selection", "--save"}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendFileArgs(args, opts)
}
if opts.directory {
args = append(args, "--directory")
}
if opts.confirmOverwrite {
args = append(args, "--confirm-overwrite")
}
if opts.filename != "" {
args = append(args, "--filename", opts.filename)
}
args = append(args, initFilters(opts.fileFilters)...)
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { str, _, err := strResult(opts, out, err)
return "", nil return str, err
}
if err != nil {
return "", err
}
return string(bytes.TrimSuffix(out, []byte{'\n'})), nil
} }
func initFilters(filters []FileFilter) []string { func initFilters(filters []FileFilter) []string {
@ -103,3 +54,18 @@ func initFilters(filters []FileFilter) []string {
} }
return res return res
} }
func appendFileArgs(args []string, opts options) []string {
if opts.directory {
args = append(args, "--directory")
}
if opts.filename != "" {
args = append(args, "--filename", opts.filename)
}
if opts.confirmOverwrite {
args = append(args, "--confirm-overwrite")
}
args = append(args, initFilters(opts.fileFilters)...)
return args
}

View file

@ -47,11 +47,8 @@ func ParseColor(s string) color.Color {
} }
} }
c, ok := colornames.Map[strings.ToLower(s)] c, _ := colornames.Map[strings.ToLower(s)]
if ok {
return c return c
}
return nil
} }
// UnparseColor is internal. // UnparseColor is internal.

View file

@ -17,7 +17,7 @@ func ListItems(text string, items ...string) (string, bool, error) {
return List(text, items) return List(text, items)
} }
// ListMultiple displays the list dialog, allowing multiple rows to be selected. // ListMultiple displays the list dialog, allowing multiple items to be selected.
// //
// Returns a nil slice on cancel, or ErrExtraButton. // Returns a nil slice on cancel, or ErrExtraButton.
// //
@ -27,19 +27,19 @@ func ListMultiple(text string, items []string, options ...Option) ([]string, err
return listMultiple(text, items, applyOptions(options)) return listMultiple(text, items, applyOptions(options))
} }
// ListMultiple displays the list dialog, allowing multiple rows to be selected. // ListMultiple displays the list dialog, allowing multiple items to be selected.
// //
// Returns a nil slice on cancel, or ErrExtraButton. // Returns a nil slice on cancel, or ErrExtraButton.
func ListMultipleItems(text string, items ...string) ([]string, error) { func ListMultipleItems(text string, items ...string) ([]string, error) {
return ListMultiple(text, items) return ListMultiple(text, items)
} }
// DefaultItems returns an Option to set the items to initally select. // DefaultItems returns an Option to set the items to initally select (Windows and macOS only).
func DefaultItems(items ...string) Option { func DefaultItems(items ...string) Option {
return funcOption(func(o *options) { o.defaultItems = items }) return funcOption(func(o *options) { o.defaultItems = items })
} }
// DisallowEmpty returns an Option to not allow zero rows to be selected (Windows and macOS only). // DisallowEmpty returns an Option to not allow zero items to be selected (Windows and macOS only).
func DisallowEmpty() Option { func DisallowEmpty() Option {
return funcOption(func(o *options) { o.disallowEmpty = true }) return funcOption(func(o *options) { o.disallowEmpty = true })
} }

View file

@ -1,10 +1,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"strings"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -19,13 +15,7 @@ func list(text string, items []string, opts options) (string, bool, error) {
data.Options.Empty = !opts.disallowEmpty data.Options.Empty = !opts.disallowEmpty
out, err := zenutil.Run(opts.ctx, "list", data) out, err := zenutil.Run(opts.ctx, "list", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { return strResult(opts, out, err)
return "", false, nil
}
if err != nil {
return "", false, err
}
return string(bytes.TrimSuffix(out, []byte{'\n'})), true, nil
} }
func listMultiple(text string, items []string, opts options) ([]string, error) { func listMultiple(text string, items []string, opts options) ([]string, error) {
@ -41,15 +31,5 @@ func listMultiple(text string, items []string, opts options) ([]string, error) {
data.Separator = zenutil.Separator data.Separator = zenutil.Separator
out, err := zenutil.Run(opts.ctx, "list", data) out, err := zenutil.Run(opts.ctx, "list", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { return lstResult(opts, out, err)
return nil, nil
}
if err != nil {
return nil, err
}
out = bytes.TrimSuffix(out, []byte{'\n'})
if len(out) == 0 {
return nil, nil
}
return strings.Split(string(out), zenutil.Separator), nil
} }

View file

@ -2,10 +2,30 @@
package zenity package zenity
import (
"github.com/ncruces/zenity/internal/zenutil"
)
func list(text string, items []string, opts options) (string, bool, error) { func list(text string, items []string, opts options) (string, bool, error) {
return "", false, nil args := []string{"--list", "--column=", "--hide-header", "--text", text}
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = append(args, items...)
out, err := zenutil.Run(opts.ctx, args)
return strResult(opts, out, err)
} }
func listMultiple(text string, items []string, opts options) ([]string, error) { func listMultiple(text string, items []string, opts options) ([]string, error) {
return nil, nil args := []string{"--list", "--column=", "--hide-header", "--text", text, "--multiple", "--separator", zenutil.Separator}
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = append(args, items...)
out, err := zenutil.Run(opts.ctx, args)
return lstResult(opts, out, err)
} }

View file

@ -1,9 +1,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -36,15 +33,6 @@ func message(kind messageKind, text string, opts options) (bool, error) {
data.SetButtons(getButtons(dialog, kind == questionKind, opts)) data.SetButtons(getButtons(dialog, kind == questionKind, opts))
out, err := zenutil.Run(opts.ctx, "dialog", data) out, err := zenutil.Run(opts.ctx, "dialog", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { _, ok, err := strResult(opts, out, err)
if opts.extraButton != nil && return ok, err
*opts.extraButton == string(bytes.TrimSuffix(out, []byte{'\n'})) {
return false, ErrExtraButton
}
return false, nil
}
if err != nil {
return false, err
}
return true, err
} }

View file

@ -3,10 +3,6 @@
package zenity package zenity
import ( import (
"bytes"
"os/exec"
"strconv"
"github.com/ncruces/zenity/internal/zenutil" "github.com/ncruces/zenity/internal/zenutil"
) )
@ -22,24 +18,10 @@ func message(kind messageKind, text string, opts options) (bool, error) {
case errorKind: case errorKind:
args = append(args, "--error") args = append(args, "--error")
} }
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title) args = appendButtons(args, opts)
} args = appendWidthHeight(args, opts)
if opts.width > 0 { args = appendIcon(args, opts)
args = append(args, "--width", strconv.FormatUint(uint64(opts.width), 10))
}
if opts.height > 0 {
args = append(args, "--height", strconv.FormatUint(uint64(opts.height), 10))
}
if opts.okLabel != nil {
args = append(args, "--ok-label", *opts.okLabel)
}
if opts.cancelLabel != nil {
args = append(args, "--cancel-label", *opts.cancelLabel)
}
if opts.extraButton != nil {
args = append(args, "--extra-button", *opts.extraButton)
}
if opts.noWrap { if opts.noWrap {
args = append(args, "--no-wrap") args = append(args, "--no-wrap")
} }
@ -51,13 +33,13 @@ func message(kind messageKind, text string, opts options) (bool, error) {
} }
switch opts.icon { switch opts.icon {
case ErrorIcon: case ErrorIcon:
args = append(args, "--window-icon=error", "--icon-name=dialog-error") args = append(args, "--icon-name=dialog-error")
case WarningIcon: case WarningIcon:
args = append(args, "--window-icon=warning", "--icon-name=dialog-warning") args = append(args, "--icon-name=dialog-warning")
case InfoIcon: case InfoIcon:
args = append(args, "--window-icon=info", "--icon-name=dialog-information") args = append(args, "--icon-name=dialog-information")
case QuestionIcon: case QuestionIcon:
args = append(args, "--window-icon=question", "--icon-name=dialog-question") args = append(args, "--icon-name=dialog-question")
case PasswordIcon: case PasswordIcon:
args = append(args, "--icon-name=dialog-password") args = append(args, "--icon-name=dialog-password")
case NoIcon: case NoIcon:
@ -65,15 +47,6 @@ func message(kind messageKind, text string, opts options) (bool, error) {
} }
out, err := zenutil.Run(opts.ctx, args) out, err := zenutil.Run(opts.ctx, args)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { _, ok, err := strResult(opts, out, err)
if opts.extraButton != nil && return ok, err
*opts.extraButton == string(bytes.TrimSuffix(out, []byte{'\n'})) {
return false, ErrExtraButton
}
return false, nil
}
if err != nil {
return false, err
}
return true, err
} }

View file

@ -8,9 +8,7 @@ import (
func notify(text string, opts options) error { func notify(text string, opts options) error {
args := []string{"--notification", "--text", text} args := []string{"--notification", "--text", text}
if opts.title != nil { args = appendTitle(args, opts)
args = append(args, "--title", *opts.title)
}
switch opts.icon { switch opts.icon {
case ErrorIcon: case ErrorIcon:
args = append(args, "--window-icon=dialog-error") args = append(args, "--window-icon=dialog-error")

78
utils_unix.go Normal file
View file

@ -0,0 +1,78 @@
// +build !windows
package zenity
import (
"bytes"
"os/exec"
"strconv"
"strings"
"github.com/ncruces/zenity/internal/zenutil"
)
func appendTitle(args []string, opts options) []string {
if opts.title != nil {
args = append(args, "--title", *opts.title)
}
return args
}
func appendButtons(args []string, opts options) []string {
if opts.okLabel != nil {
args = append(args, "--ok-label", *opts.okLabel)
}
if opts.cancelLabel != nil {
args = append(args, "--cancel-label", *opts.cancelLabel)
}
if opts.extraButton != nil {
args = append(args, "--extra-button", *opts.extraButton)
}
return args
}
func appendWidthHeight(args []string, opts options) []string {
if opts.width > 0 {
args = append(args, "--width", strconv.FormatUint(uint64(opts.width), 10))
}
if opts.height > 0 {
args = append(args, "--height", strconv.FormatUint(uint64(opts.height), 10))
}
return args
}
func appendIcon(args []string, opts options) []string {
switch opts.icon {
case ErrorIcon:
args = append(args, "--window-icon=error")
case WarningIcon:
args = append(args, "--window-icon=warning")
case InfoIcon:
args = append(args, "--window-icon=info")
case QuestionIcon:
args = append(args, "--window-icon=question")
}
return args
}
func strResult(opts options, out []byte, err error) (string, bool, error) {
out = bytes.TrimSuffix(out, []byte{'\n'})
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
if opts.extraButton != nil && *opts.extraButton == string(out) {
return "", false, ErrExtraButton
}
return "", false, nil
}
if err != nil {
return "", false, err
}
return string(out), true, nil
}
func lstResult(opts options, out []byte, err error) ([]string, error) {
str, ok, err := strResult(opts, out, err)
if ok {
return strings.Split(str, zenutil.Separator), nil
}
return nil, err
}