package filechooser import ( "github.com/godbus/dbus/v5" "github.com/rymdport/portal/internal/apis" "github.com/rymdport/portal/internal/convert" ) const ( saveFileCallName = interfaceName + ".SaveFile" saveFilesCallName = interfaceName + ".SaveFiles" ) // SaveFileOptions contains the options for how a file is saved. type SaveFileOptions struct { HandleToken string // A string that will be used as the last element of the handle. Must be a valid object path element. AcceptLabel string // Label for the accept button. Mnemonic underlines are allowed. NotModal bool // Whether the dialog should not be modal. Filters []*Filter // Each item specifies a single filter to offer to the user. CurrentFilter *Filter // Request that this filter be set by default at dialog creation. Choices []*ComboBox // List of serialized combo boxes to add to the file chooser. CurrentFolder string // Suggested folder in which the file should be saved. CurrentName string // Suggested name of the file. } // SaveFile opens a filechooser for selecting where to save a file. // The chooser will use the supplied title as it's name. func SaveFile(parentWindow, title string, options *SaveFileOptions) ([]string, error) { data := map[string]dbus.Variant{} if options != nil { data = map[string]dbus.Variant{ "modal": convert.FromBool(!options.NotModal), } if options.HandleToken != "" { data["handle_token"] = convert.FromString(options.HandleToken) } if options.AcceptLabel != "" { data["accept_label"] = convert.FromString(options.AcceptLabel) } if len(options.Filters) > 0 { data["filters"] = dbus.MakeVariant(options.Filters) } if options.CurrentFilter != nil { data["current_filter"] = dbus.MakeVariant(options.CurrentFilter) } if len(options.Choices) > 0 { data["choices"] = dbus.MakeVariant(options.Choices) } if options.CurrentName != "" { data["current_name"] = convert.FromString(options.CurrentName) } if options.CurrentFolder != "" { data["current_folder"] = convert.ToNullTerminatedValue(options.CurrentFolder) } } result, err := apis.Call(saveFileCallName, parentWindow, title, data) if err != nil { return nil, err } return readURIFromResponse(result.(dbus.ObjectPath)) } // SaveFilesOptions contains the options for how files are saved. type SaveFilesOptions struct { HandleToken string // A string that will be used as the last element of the handle. Must be a valid object path element. AcceptLabel string // Label for the accept button. Mnemonic underlines are allowed. NotModal bool // Whether the dialog should be modal. Choices []*ComboBox // List of serialized combo boxes to add to the file chooser. CurrentFolder string // Suggested folder in which the file should be saved. Files []string // An array of file names to be saved. } // SaveFiles opens a filechooser for selecting where to save one or more files. // The chooser will use the supplied title as it's name. func SaveFiles(parentWindow, title string, options *SaveFilesOptions) ([]string, error) { data := map[string]dbus.Variant{} if options != nil { data = map[string]dbus.Variant{ "modal": convert.FromBool(!options.NotModal), } if options.HandleToken != "" { data["handle_token"] = convert.FromString(options.HandleToken) } if options.AcceptLabel != "" { data["accept_label"] = convert.FromString(options.AcceptLabel) } if len(options.Choices) > 0 { data["choices"] = dbus.MakeVariant(options.Choices) } if options.CurrentFolder != "" { data["current_folder"] = convert.ToNullTerminatedValue(options.CurrentFolder) } if len(options.Files) > 0 { files := make([][]byte, len(options.Files)) for i, file := range options.Files { files[i] = convert.FromStringToNullTerminated(file) } data["files"] = dbus.MakeVariant(files) } } result, err := apis.Call(saveFilesCallName, parentWindow, title, data) if err != nil { return nil, err } return readURIFromResponse(result.(dbus.ObjectPath)) }