From 7f608be6c269568a54bbe365ffad2eae201d2bef Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Wed, 8 Jan 2020 18:12:29 +0000 Subject: [PATCH] WIP: zenity command. --- cmd/zenity/main.go | 192 ++++++++++++++++++++++++++++++++-- file_linux.go => file_unix.go | 2 + go.mod | 2 + go.sum | 2 + internal/cmd/cmd_unix.go | 5 + internal/cmd/cmd_windows.go | 3 + msg_linux.go => msg_unix.go | 2 + 7 files changed, 200 insertions(+), 8 deletions(-) rename file_linux.go => file_unix.go (99%) create mode 100644 go.sum create mode 100644 internal/cmd/cmd_unix.go create mode 100644 internal/cmd/cmd_windows.go rename msg_linux.go => msg_unix.go (98%) diff --git a/cmd/zenity/main.go b/cmd/zenity/main.go index 02574a8..29040ed 100644 --- a/cmd/zenity/main.go +++ b/cmd/zenity/main.go @@ -1,24 +1,200 @@ package main import ( + "flag" "os" + "strings" + + "rsc.io/getopt" "github.com/ncruces/zenity" "github.com/ncruces/zenity/internal/cmd" ) +var ( + // Application Options + errorDlg bool + infoDlg bool + warningDlg bool + questionDlg bool + fileSelectionDlg bool + + // General options + title string + + // Message options + text string + iconName string + okLabel string + cancelLabel string + extraButton string + noWrap bool + ellipsize bool + defaultCancel bool + + // File selection options + save bool + multiple bool + directory bool + confirmOverwrite bool + filename string + separator string + fileFilters FileFilters +) + func main() { + setupFlags() + getopt.Parse() + validateFlags() + opts := loadFlags() cmd.Command = true - file, err := zenity.SelectFile() - if err != nil { - os.Stderr.WriteString(err.Error()) - os.Stderr.WriteString("\n") - os.Exit(255) + switch { + case errorDlg: + msgResult(zenity.Error(text, opts...)) + case infoDlg: + msgResult(zenity.Info(text, opts...)) + case warningDlg: + msgResult(zenity.Warning(text, opts...)) + case questionDlg: + msgResult(zenity.Question(text, opts...)) } - if file == "" { + + flag.Usage() + os.Exit(-1) +} + +func setupFlags() { + // Application Options + + flag.BoolVar(&errorDlg, "error", false, "Display error dialog") + flag.BoolVar(&infoDlg, "info", false, "Display info dialog") + flag.BoolVar(&warningDlg, "warning", false, "Display warning dialog") + flag.BoolVar(&questionDlg, "question", false, "Display question dialog") + flag.BoolVar(&fileSelectionDlg, "file-selection", false, "Display file selection dialog") + + // General options + + flag.StringVar(&title, "title", "", "Set the dialog title") + + // Message options + + flag.StringVar(&text, "text", "", "Set the dialog text") + flag.StringVar(&iconName, "icon-name", "", "Set the dialog icon (error, information, question, warning)") + flag.StringVar(&okLabel, "ok-label", "", "Set the label of the OK button") + flag.StringVar(&cancelLabel, "cancel-label", "", "Set the label of the Cancel button") + flag.StringVar(&extraButton, "extra-button", "", "Add an extra button") + flag.BoolVar(&noWrap, "no-wrap", false, "Do not enable text wrapping") + flag.BoolVar(&ellipsize, "ellipsize", false, "Enable ellipsizing in the dialog text") + flag.BoolVar(&defaultCancel, "default-cancel", false, "Give Cancel button focus by default") + + // File selection options + + flag.BoolVar(&save, "save", false, "Activate save mode") + flag.BoolVar(&multiple, "multiple", false, "Allow multiple files to be selected") + 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.Var(&fileFilters, "file-filter", "Set a filename filter (NAME | PATTERN1 PATTERN2 ...)") +} + +func validateFlags() { + var n int + if errorDlg { + n++ + } + if infoDlg { + n++ + } + if warningDlg { + n++ + } + if questionDlg { + n++ + } + if fileSelectionDlg { + n++ + } + if n != 1 { + flag.Usage() + os.Exit(-1) + } +} + +func loadFlags() []zenity.Option { + var options []zenity.Option + + // General options + + options = append(options, zenity.Title(title)) + + // Message options + + var icon zenity.MessageIcon + switch iconName { + case "error", "dialog-error": + icon = zenity.ErrorIcon + case "info", "dialog-information": + icon = zenity.InfoIcon + case "question", "dialog-question": + icon = zenity.QuestionIcon + case "warning", "dialog-warning": + icon = zenity.WarningIcon + } + + options = append(options, zenity.Icon(icon)) + options = append(options, zenity.OKLabel(okLabel)) + options = append(options, zenity.CancelLabel(cancelLabel)) + options = append(options, zenity.ExtraButton(extraButton)) + if noWrap { + options = append(options, zenity.NoWrap) + } + if ellipsize { + options = append(options, zenity.Ellipsize) + } + if defaultCancel { + options = append(options, zenity.DefaultCancel) + } + + return options +} + +func msgResult(ok bool, err error) { + if err == zenity.ErrExtraButton { + os.Stdout.WriteString(extraButton) + os.Stdout.WriteString(cmd.LineBreak) os.Exit(1) } - os.Stdout.WriteString(file) - os.Stdout.WriteString("\n") + if err != nil { + os.Stderr.WriteString(err.Error()) + os.Stderr.WriteString(cmd.LineBreak) + os.Exit(-1) + } + if ok { + os.Exit(0) + } + os.Exit(1) +} + +type FileFilters struct { + list []zenity.FileFilter +} + +func (f *FileFilters) String() string { + return "filename filter" +} + +func (f *FileFilters) Set(s string) error { + var filter zenity.FileFilter + + if split := strings.SplitN(s, "|", 2); len(split) > 0 { + filter.Name = split[0] + s = split[1] + } + + filter.Exts = strings.Split(s, " ") + f.list = append(f.list, filter) + + return nil } diff --git a/file_linux.go b/file_unix.go similarity index 99% rename from file_linux.go rename to file_unix.go index c3c644c..33b851b 100644 --- a/file_linux.go +++ b/file_unix.go @@ -1,3 +1,5 @@ +// +build !windows,!darwin + package zenity import ( diff --git a/go.mod b/go.mod index b62b7b6..baba0a3 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/ncruces/zenity go 1.13 + +require rsc.io/getopt v0.0.0-20170811000552-20be20937449 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5894729 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +rsc.io/getopt v0.0.0-20170811000552-20be20937449 h1:UukjJOsjQH0DIuyyrcod6CXHS6cdaMMuJmrt+SN1j4A= +rsc.io/getopt v0.0.0-20170811000552-20be20937449/go.mod h1:dhCdeqAxkyt5u3/sKRkUXuHaMXUu1Pt13GTQAM2xnig= diff --git a/internal/cmd/cmd_unix.go b/internal/cmd/cmd_unix.go new file mode 100644 index 0000000..c3f757d --- /dev/null +++ b/internal/cmd/cmd_unix.go @@ -0,0 +1,5 @@ +// +build !windows + +package cmd + +const LineBreak = "\n" diff --git a/internal/cmd/cmd_windows.go b/internal/cmd/cmd_windows.go new file mode 100644 index 0000000..94a2f78 --- /dev/null +++ b/internal/cmd/cmd_windows.go @@ -0,0 +1,3 @@ +package cmd + +const LineBreak = "\r\n" diff --git a/msg_linux.go b/msg_unix.go similarity index 98% rename from msg_linux.go rename to msg_unix.go index 0b42c81..00ae017 100644 --- a/msg_linux.go +++ b/msg_unix.go @@ -1,3 +1,5 @@ +// +build !windows,!darwin + package zenity import "os/exec"