From 6c0abac1c5c5f22363364ce02d52aba8b902d296 Mon Sep 17 00:00:00 2001 From: Leonid Nikitin Date: Sun, 8 Jun 2025 00:18:56 +0500 Subject: [PATCH] Add directory selection for saving converted files Introduce logic and UI for selecting and persisting a directory to save converted files. Extend existing components with directory selection buttons, message updates, and storage preferences. --- internal/application/setting/setting.go | 14 +++++ internal/controller/convertor.go | 11 +++- internal/gui/view/convertor.go | 83 ++++++++++++++++++++++++- internal/utils/path.go | 19 ++++++ 4 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 internal/utils/path.go diff --git a/internal/application/setting/setting.go b/internal/application/setting/setting.go index d10d324..f969edc 100644 --- a/internal/application/setting/setting.go +++ b/internal/application/setting/setting.go @@ -10,10 +10,16 @@ type SettingContract interface { GetLanguages() []Lang GetCurrentLangOrDefaultLang() (currentLang Lang, isDefault bool) SetLang(language Lang) error + + GetDirectoryForSaving() string + SetDirectoryForSaving(path string) + GetFFmpegPath() string SetFFmpegPath(path string) + GetFFprobePath() string SetFFprobePath(path string) + GetFFplayPath() string SetFFplayPath(path string) } @@ -63,3 +69,11 @@ func (s *setting) SetLang(language Lang) error { s.fyneApp.Preferences().SetString("language", language.Code) return nil } + +func (s *setting) GetDirectoryForSaving() string { + return s.fyneApp.Preferences().String("directoryForSaving") +} + +func (s *setting) SetDirectoryForSaving(path string) { + s.fyneApp.Preferences().SetString("directoryForSaving", path) +} diff --git a/internal/controller/convertor.go b/internal/controller/convertor.go index 4037000..898e3fd 100644 --- a/internal/controller/convertor.go +++ b/internal/controller/convertor.go @@ -7,7 +7,12 @@ import ( ) func (c *controller) convertor() { - content := view.Convertor(c.window, c.addFileForConversion) + content := view.Convertor( + c.window, + c.addFileForConversion, + c.app.GetSetting().GetDirectoryForSaving(), + c.setDirectoryForSaving, + ) c.window.SetContent(content) } @@ -16,6 +21,10 @@ func (c *controller) addFileForConversion(file ffmpeg.File) { c.window.GetLayout().GetRContainer().SelectAddedFilesTab() } +func (c *controller) setDirectoryForSaving(path string) { + c.app.GetSetting().SetDirectoryForSaving(path) +} + func (c *controller) settingConvertor(isAllowCancellation bool) { ffmpegPath := c.app.GetFFmpegService().GetFFmpegPath() ffprobePath := c.app.GetFFmpegService().GetFFprobePath() diff --git a/internal/gui/view/convertor.go b/internal/gui/view/convertor.go index 41a3cb8..8f52592 100644 --- a/internal/gui/view/convertor.go +++ b/internal/gui/view/convertor.go @@ -17,8 +17,18 @@ import ( "path/filepath" ) -func Convertor(window window.WindowContract, addFileForConversion func(file ffmpeg.File)) fyne.CanvasObject { - form := newFormConvertor(window, addFileForConversion) +func Convertor( + window window.WindowContract, + addFileForConversion func(file ffmpeg.File), + directoryForSavingPath string, + directoryForSaving func(path string), +) fyne.CanvasObject { + form := newFormConvertor( + window, + addFileForConversion, + directoryForSavingPath, + directoryForSaving, + ) converterVideoFilesTitle := lang.L("converterVideoFilesTitle") return widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(form.getForm())) @@ -30,9 +40,15 @@ type formConvertor struct { window window.WindowContract addFileForConversion func(file ffmpeg.File) + directoryForSaving func(path string) } -func newFormConvertor(window window.WindowContract, addFileForConversion func(file ffmpeg.File)) *formConvertor { +func newFormConvertor( + window window.WindowContract, + addFileForConversion func(file ffmpeg.File), + directoryForSavingPath string, + directoryForSaving func(path string), +) *formConvertor { f := widget.NewForm() f.SubmitText = lang.L("converterVideoFilesSubmitTitle") @@ -40,9 +56,11 @@ func newFormConvertor(window window.WindowContract, addFileForConversion func(fi form: f, window: window, addFileForConversion: addFileForConversion, + directoryForSaving: directoryForSaving, } fileForConversion := formConvertor.newFileForConversion() + directoryForSavingButton := formConvertor.newDirectoryForSaving(directoryForSavingPath) items := []*widget.FormItem{ { @@ -52,6 +70,14 @@ func newFormConvertor(window window.WindowContract, addFileForConversion func(fi { Widget: container.NewHScroll(fileForConversion.message), }, + + { + Text: lang.L("buttonForSelectedDirTitle"), + Widget: directoryForSavingButton.button, + }, + { + Widget: container.NewHScroll(directoryForSavingButton.message), + }, } formConvertor.form.Items = items formConvertor.items = items @@ -161,6 +187,57 @@ func (f *formConvertor) newFileForConversion() *fileForConversion { return fileForConversion } +type directoryForSaving struct { + button *widget.Button + message *canvas.Text + path string +} + +func (f *formConvertor) newDirectoryForSaving(directoryForSavingPath string) *directoryForSaving { + directoryForSaving := &directoryForSaving{ + path: "", + } + + directoryForSaving.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255}) + directoryForSaving.message.TextSize = 16 + directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true} + + buttonTitle := lang.L("choose") + + locationURI, err := utils.PathToListableURI(directoryForSavingPath) + if err == nil { + directoryForSaving.path = locationURI.Path() + directoryForSaving.message.Text = locationURI.Path() + utils.SetStringSuccessStyle(directoryForSaving.message) + } + + directoryForSaving.button = widget.NewButton(buttonTitle, func() { + f.window.NewFolderOpen(func(r fyne.ListableURI, err error) { + if err != nil { + directoryForSaving.message.Text = err.Error() + utils.SetStringErrorStyle(directoryForSaving.message) + return + } + if r == nil { + return + } + + directoryForSaving.path = r.Path() + + directoryForSaving.message.Text = r.Path() + utils.SetStringSuccessStyle(directoryForSaving.message) + locationURI, err = storage.ListerForURI(r) + + if err == nil { + f.directoryForSaving(locationURI.Path()) + } + + }, locationURI) + }) + + return directoryForSaving +} + func (c *fileForConversion) addChangeCallback(callback func(err error)) { c.changeCallbacks[len(c.changeCallbacks)] = callback } diff --git a/internal/utils/path.go b/internal/utils/path.go new file mode 100644 index 0000000..4a35d20 --- /dev/null +++ b/internal/utils/path.go @@ -0,0 +1,19 @@ +package utils + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/storage" +) + +func PathToListableURI(path string) (fyne.ListableURI, error) { + if len(path) > 0 { + path = "file://" + path + } + + uri, err := storage.ParseURI(path) + if err != nil { + return nil, err + } + + return storage.ListerForURI(uri) +}