Save and replace profiles via system file dialog; buttons after Best; prefs unchanged on import. Co-authored-by: Cursor <cursoragent@cursor.com>
80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
//go:build darwin
|
|
|
|
package filedialog
|
|
|
|
import (
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
func appleScriptQuote(s string) string {
|
|
s = strings.ReplaceAll(s, `\`, `\\`)
|
|
return strings.ReplaceAll(s, `"`, `\"`)
|
|
}
|
|
|
|
// SaveJSON shows a Save As dialog for a .json file.
|
|
func SaveJSON(title, defaultName string) (string, error) {
|
|
if title == "" {
|
|
title = "Сохранить список серверов"
|
|
}
|
|
if defaultName == "" {
|
|
defaultName = "navis-servers.json"
|
|
}
|
|
script := `try
|
|
set thePath to POSIX path of (choose file name with prompt "` + appleScriptQuote(title) + `" default name "` + appleScriptQuote(defaultName) + `")
|
|
return thePath
|
|
on error number -128
|
|
error "canceled"
|
|
end try`
|
|
out, err := exec.Command("osascript", "-e", script).Output()
|
|
if err != nil {
|
|
if strings.Contains(string(out), "canceled") || strings.Contains(err.Error(), "canceled") {
|
|
return "", ErrCanceled
|
|
}
|
|
// osascript writes AppleScript errors to stderr; treat cancel-ish exits as cancel.
|
|
if exit, ok := err.(*exec.ExitError); ok && exit.ExitCode() != 0 {
|
|
msg := strings.ToLower(string(exit.Stderr) + string(out) + err.Error())
|
|
if strings.Contains(msg, "cancel") || strings.Contains(msg, "-128") {
|
|
return "", ErrCanceled
|
|
}
|
|
}
|
|
return "", err
|
|
}
|
|
path := strings.TrimSpace(string(out))
|
|
if path == "" {
|
|
return "", ErrCanceled
|
|
}
|
|
if !strings.HasSuffix(strings.ToLower(path), ".json") {
|
|
path += ".json"
|
|
}
|
|
return path, nil
|
|
}
|
|
|
|
// OpenJSON shows an Open dialog for a .json file.
|
|
func OpenJSON(title string) (string, error) {
|
|
if title == "" {
|
|
title = "Загрузить список серверов"
|
|
}
|
|
script := `try
|
|
set theFile to choose file with prompt "` + appleScriptQuote(title) + `" of type {"public.json", "json", "public.plain-text"}
|
|
return POSIX path of theFile
|
|
on error number -128
|
|
error "canceled"
|
|
end try`
|
|
out, err := exec.Command("osascript", "-e", script).Output()
|
|
if err != nil {
|
|
if exit, ok := err.(*exec.ExitError); ok {
|
|
msg := strings.ToLower(string(exit.Stderr) + string(out) + err.Error())
|
|
if strings.Contains(msg, "cancel") || strings.Contains(msg, "-128") {
|
|
return "", ErrCanceled
|
|
}
|
|
}
|
|
return "", err
|
|
}
|
|
path := strings.TrimSpace(string(out))
|
|
if path == "" {
|
|
return "", ErrCanceled
|
|
}
|
|
return path, nil
|
|
}
|