From 08ed75b4c598c4bbdfc716fd69e71aead78ab83c Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Thu, 8 Apr 2021 16:43:14 +0100 Subject: [PATCH] List (unix), refactor. --- color_darwin.go | 11 ++--- color_unix.go | 15 +++---- entry_darwin.go | 20 ++------- entry_unix.go | 81 ++++++------------------------------ file_darwin.go | 32 +++------------ file_unix.go | 86 ++++++++++++--------------------------- internal/zenutil/color.go | 7 +--- list.go | 8 ++-- list_darwin.go | 24 +---------- list_unix.go | 24 ++++++++++- msg_darwin.go | 16 +------- msg_unix.go | 47 +++++---------------- notify_unix.go | 4 +- utils_unix.go | 78 +++++++++++++++++++++++++++++++++++ 14 files changed, 177 insertions(+), 276 deletions(-) create mode 100644 utils_unix.go diff --git a/color_darwin.go b/color_darwin.go index 138c305..4b745a2 100644 --- a/color_darwin.go +++ b/color_darwin.go @@ -2,7 +2,6 @@ package zenity import ( "image/color" - "os/exec" "github.com/ncruces/zenity/internal/zenutil" ) @@ -21,11 +20,9 @@ func selectColor(opts options) (color.Color, error) { float32(g) / 0xffff, float32(b) / 0xffff, }) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return nil, nil + str, ok, err := strResult(opts, out, err) + if ok { + return zenutil.ParseColor(str), nil } - if err != nil { - return nil, err - } - return zenutil.ParseColor(string(out)), nil + return nil, err } diff --git a/color_unix.go b/color_unix.go index 83614d9..464e0d1 100644 --- a/color_unix.go +++ b/color_unix.go @@ -4,7 +4,6 @@ package zenity import ( "image/color" - "os/exec" "github.com/ncruces/zenity/internal/zenutil" ) @@ -12,9 +11,7 @@ import ( func selectColor(opts options) (color.Color, error) { args := []string{"--color-selection"} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } + args = appendTitle(args, opts) if opts.color != nil { 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) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return nil, nil + str, ok, err := strResult(opts, out, err) + if ok { + return zenutil.ParseColor(str), nil } - if err != nil { - return nil, err - } - return zenutil.ParseColor(string(out)), nil + return nil, err } diff --git a/entry_darwin.go b/entry_darwin.go index 4867ca6..5f0da90 100644 --- a/entry_darwin.go +++ b/entry_darwin.go @@ -1,9 +1,6 @@ package zenity import ( - "bytes" - "os/exec" - "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)) out, err := zenutil.Run(opts.ctx, "dialog", data) - 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 + return strResult(opts, out, err) } func password(opts options) (string, string, bool, error) { opts.hideText = true - pass, ok, err := entry("Password:", opts) - return "", pass, ok, err + str, ok, err := entry("Password:", opts) + return "", str, ok, err } diff --git a/entry_unix.go b/entry_unix.go index d6361ed..dca67de 100644 --- a/entry_unix.go +++ b/entry_unix.go @@ -3,97 +3,42 @@ package zenity import ( - "bytes" - "os/exec" - "strconv" "strings" "github.com/ncruces/zenity/internal/zenutil" ) func entry(text string, opts options) (string, bool, error) { - args := []string{"--entry", "--text", text, "--entry-text", opts.entryText} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - 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)) - } - 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) + args := []string{"--entry", "--text", text} + args = appendTitle(args, opts) + args = appendButtons(args, opts) + args = appendWidthHeight(args, opts) + args = appendIcon(args, opts) + if opts.entryText != "" { + args = append(args, "--entry-text", opts.entryText) } if opts.hideText { 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 = 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 + return strResult(opts, out, err) } func password(opts options) (string, string, bool, error) { args := []string{"--password"} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - 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) - } + args = appendTitle(args, opts) + args = appendButtons(args, opts) if opts.username { args = append(args, "--username") } out, err := zenutil.Run(opts.ctx, args) - 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 - } - if opts.username { + str, ok, err := strResult(opts, out, err) + if ok && opts.username { if split := strings.SplitN(string(out), "|", 2); len(split) == 2 { return split[0], split[1], true, nil } } - return "", string(out), true, nil + return "", str, ok, err } diff --git a/file_darwin.go b/file_darwin.go index 275d234..438b83a 100644 --- a/file_darwin.go +++ b/file_darwin.go @@ -1,8 +1,6 @@ package zenity import ( - "bytes" - "os/exec" "strings" "github.com/ncruces/zenity/internal/zenutil" @@ -22,13 +20,8 @@ func selectFile(opts options) (string, error) { } out, err := zenutil.Run(opts.ctx, "file", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return "", nil - } - if err != nil { - return "", err - } - return string(bytes.TrimSuffix(out, []byte{'\n'})), nil + str, _, err := strResult(opts, out, err) + return str, err } func selectFileMutiple(opts options) ([]string, error) { @@ -47,17 +40,7 @@ func selectFileMutiple(opts options) ([]string, error) { } out, err := zenutil.Run(opts.ctx, "file", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - 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 + return lstResult(opts, out, err) } func selectFileSave(opts options) (string, error) { @@ -73,13 +56,8 @@ func selectFileSave(opts options) (string, error) { } out, err := zenutil.Run(opts.ctx, "file", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return "", nil - } - if err != nil { - return "", err - } - return string(bytes.TrimSuffix(out, []byte{'\n'})), nil + str, _, err := strResult(opts, out, err) + return str, err } func initFilters(filters []FileFilter) []string { diff --git a/file_unix.go b/file_unix.go index a9be018..347e205 100644 --- a/file_unix.go +++ b/file_unix.go @@ -3,8 +3,6 @@ package zenity import ( - "bytes" - "os/exec" "strings" "github.com/ncruces/zenity/internal/zenutil" @@ -12,78 +10,31 @@ import ( func selectFile(opts options) (string, error) { args := []string{"--file-selection"} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - if opts.directory { - args = append(args, "--directory") - } - if opts.filename != "" { - args = append(args, "--filename", opts.filename) - } - args = append(args, initFilters(opts.fileFilters)...) + args = appendTitle(args, opts) + args = appendFileArgs(args, opts) out, err := zenutil.Run(opts.ctx, args) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return "", nil - } - if err != nil { - return "", err - } - return string(bytes.TrimSuffix(out, []byte{'\n'})), nil + str, _, err := strResult(opts, out, err) + return str, err } func selectFileMutiple(opts options) ([]string, error) { args := []string{"--file-selection", "--multiple", "--separator", zenutil.Separator} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - if opts.directory { - args = append(args, "--directory") - } - if opts.filename != "" { - args = append(args, "--filename", opts.filename) - } - args = append(args, initFilters(opts.fileFilters)...) + args = appendTitle(args, opts) + args = appendFileArgs(args, opts) out, err := zenutil.Run(opts.ctx, args) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - 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 + return lstResult(opts, out, err) } func selectFileSave(opts options) (string, error) { args := []string{"--file-selection", "--save"} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - 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)...) + args = appendTitle(args, opts) + args = appendFileArgs(args, opts) out, err := zenutil.Run(opts.ctx, args) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return "", nil - } - if err != nil { - return "", err - } - return string(bytes.TrimSuffix(out, []byte{'\n'})), nil + str, _, err := strResult(opts, out, err) + return str, err } func initFilters(filters []FileFilter) []string { @@ -103,3 +54,18 @@ func initFilters(filters []FileFilter) []string { } 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 +} diff --git a/internal/zenutil/color.go b/internal/zenutil/color.go index 8388270..0cd82a7 100644 --- a/internal/zenutil/color.go +++ b/internal/zenutil/color.go @@ -47,11 +47,8 @@ func ParseColor(s string) color.Color { } } - c, ok := colornames.Map[strings.ToLower(s)] - if ok { - return c - } - return nil + c, _ := colornames.Map[strings.ToLower(s)] + return c } // UnparseColor is internal. diff --git a/list.go b/list.go index c4dc9b3..fb6dc22 100644 --- a/list.go +++ b/list.go @@ -17,7 +17,7 @@ func ListItems(text string, items ...string) (string, bool, error) { 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. // @@ -27,19 +27,19 @@ func ListMultiple(text string, items []string, options ...Option) ([]string, err 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. func ListMultipleItems(text string, items ...string) ([]string, error) { 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 { 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 { return funcOption(func(o *options) { o.disallowEmpty = true }) } diff --git a/list_darwin.go b/list_darwin.go index 2f77698..a6b2be0 100644 --- a/list_darwin.go +++ b/list_darwin.go @@ -1,10 +1,6 @@ package zenity import ( - "bytes" - "os/exec" - "strings" - "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 out, err := zenutil.Run(opts.ctx, "list", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - return "", false, nil - } - if err != nil { - return "", false, err - } - return string(bytes.TrimSuffix(out, []byte{'\n'})), true, nil + return strResult(opts, out, err) } 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 out, err := zenutil.Run(opts.ctx, "list", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - 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 + return lstResult(opts, out, err) } diff --git a/list_unix.go b/list_unix.go index 3172cec..db6aad0 100644 --- a/list_unix.go +++ b/list_unix.go @@ -2,10 +2,30 @@ package zenity +import ( + "github.com/ncruces/zenity/internal/zenutil" +) + 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) { - 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) } diff --git a/msg_darwin.go b/msg_darwin.go index 3cc4a34..03a1827 100644 --- a/msg_darwin.go +++ b/msg_darwin.go @@ -1,9 +1,6 @@ package zenity import ( - "bytes" - "os/exec" - "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)) out, err := zenutil.Run(opts.ctx, "dialog", data) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - if opts.extraButton != nil && - *opts.extraButton == string(bytes.TrimSuffix(out, []byte{'\n'})) { - return false, ErrExtraButton - } - return false, nil - } - if err != nil { - return false, err - } - return true, err + _, ok, err := strResult(opts, out, err) + return ok, err } diff --git a/msg_unix.go b/msg_unix.go index 85249d0..bcdf794 100644 --- a/msg_unix.go +++ b/msg_unix.go @@ -3,10 +3,6 @@ package zenity import ( - "bytes" - "os/exec" - "strconv" - "github.com/ncruces/zenity/internal/zenutil" ) @@ -22,24 +18,10 @@ func message(kind messageKind, text string, opts options) (bool, error) { case errorKind: args = append(args, "--error") } - if opts.title != nil { - args = append(args, "--title", *opts.title) - } - 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)) - } - 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) - } + args = appendTitle(args, opts) + args = appendButtons(args, opts) + args = appendWidthHeight(args, opts) + args = appendIcon(args, opts) if opts.noWrap { args = append(args, "--no-wrap") } @@ -51,13 +33,13 @@ func message(kind messageKind, text string, opts options) (bool, error) { } switch opts.icon { case ErrorIcon: - args = append(args, "--window-icon=error", "--icon-name=dialog-error") + args = append(args, "--icon-name=dialog-error") case WarningIcon: - args = append(args, "--window-icon=warning", "--icon-name=dialog-warning") + args = append(args, "--icon-name=dialog-warning") case InfoIcon: - args = append(args, "--window-icon=info", "--icon-name=dialog-information") + args = append(args, "--icon-name=dialog-information") case QuestionIcon: - args = append(args, "--window-icon=question", "--icon-name=dialog-question") + args = append(args, "--icon-name=dialog-question") case PasswordIcon: args = append(args, "--icon-name=dialog-password") case NoIcon: @@ -65,15 +47,6 @@ func message(kind messageKind, text string, opts options) (bool, error) { } out, err := zenutil.Run(opts.ctx, args) - if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { - if opts.extraButton != nil && - *opts.extraButton == string(bytes.TrimSuffix(out, []byte{'\n'})) { - return false, ErrExtraButton - } - return false, nil - } - if err != nil { - return false, err - } - return true, err + _, ok, err := strResult(opts, out, err) + return ok, err } diff --git a/notify_unix.go b/notify_unix.go index f8204f4..5c040d6 100644 --- a/notify_unix.go +++ b/notify_unix.go @@ -8,9 +8,7 @@ import ( func notify(text string, opts options) error { args := []string{"--notification", "--text", text} - if opts.title != nil { - args = append(args, "--title", *opts.title) - } + args = appendTitle(args, opts) switch opts.icon { case ErrorIcon: args = append(args, "--window-icon=dialog-error") diff --git a/utils_unix.go b/utils_unix.go new file mode 100644 index 0000000..792fc6c --- /dev/null +++ b/utils_unix.go @@ -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 +}