415 lines
11 KiB
Go
415 lines
11 KiB
Go
package view
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/canvas"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/lang"
|
|
"fyne.io/fyne/v2/storage"
|
|
"fyne.io/fyne/v2/widget"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor/encoder"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
|
|
encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
|
|
"image/color"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
type ConvertSetting struct {
|
|
DirectoryForSave string
|
|
OverwriteOutputFiles bool
|
|
Format string
|
|
Encoder encoder2.EncoderContract
|
|
}
|
|
|
|
func Convertor(
|
|
window window.WindowContract,
|
|
addFileForConversion func(file ffmpeg.File),
|
|
directoryForSavingPath string,
|
|
directoryForSaving func(path string),
|
|
formats encoder.ConvertorFormatsContract,
|
|
addToConversion func(convertSetting ConvertSetting) error,
|
|
) fyne.CanvasObject {
|
|
conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
|
conversionMessage.TextSize = 16
|
|
conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
form := newFormConvertor(
|
|
window,
|
|
addFileForConversion,
|
|
directoryForSavingPath,
|
|
directoryForSaving,
|
|
formats,
|
|
addToConversion,
|
|
conversionMessage,
|
|
)
|
|
|
|
converterVideoFilesTitle := lang.L("converterVideoFilesTitle")
|
|
return widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(form.getForm()))
|
|
}
|
|
|
|
type formConvertor struct {
|
|
form *widget.Form
|
|
items []*widget.FormItem
|
|
conversionMessage *canvas.Text
|
|
|
|
window window.WindowContract
|
|
addFileForConversion func(file ffmpeg.File)
|
|
directoryForSaving func(path string)
|
|
}
|
|
|
|
func newFormConvertor(
|
|
window window.WindowContract,
|
|
addFileForConversion func(file ffmpeg.File),
|
|
directoryForSavingPath string,
|
|
directoryForSaving func(path string),
|
|
formats encoder.ConvertorFormatsContract,
|
|
addToConversion func(convertSetting ConvertSetting) error,
|
|
conversionMessage *canvas.Text,
|
|
) *formConvertor {
|
|
f := widget.NewForm()
|
|
f.SubmitText = lang.L("converterVideoFilesSubmitTitle")
|
|
|
|
formConvertor := &formConvertor{
|
|
form: f,
|
|
window: window,
|
|
addFileForConversion: addFileForConversion,
|
|
directoryForSaving: directoryForSaving,
|
|
conversionMessage: conversionMessage,
|
|
}
|
|
|
|
fileForConversion := formConvertor.newFileForConversion()
|
|
directoryForSavingButton := formConvertor.newDirectoryForSaving(directoryForSavingPath)
|
|
isOverwriteOutputFiles := false
|
|
checkboxOverwriteOutputFiles := widget.NewCheck(lang.L("checkboxOverwriteOutputFilesTitle"), func(b bool) {
|
|
isOverwriteOutputFiles = b
|
|
})
|
|
checkboxOverwriteOutputFiles.SetChecked(isOverwriteOutputFiles)
|
|
selectEncoder := formConvertor.newSelectEncoder(formats)
|
|
|
|
items := []*widget.FormItem{
|
|
{
|
|
Text: lang.L("fileForConversionTitle"),
|
|
Widget: fileForConversion.button,
|
|
},
|
|
{
|
|
Widget: container.NewHScroll(fileForConversion.message),
|
|
},
|
|
|
|
{
|
|
Text: lang.L("buttonForSelectedDirTitle"),
|
|
Widget: directoryForSavingButton.button,
|
|
},
|
|
{
|
|
Widget: container.NewHScroll(directoryForSavingButton.message),
|
|
},
|
|
|
|
{
|
|
Widget: checkboxOverwriteOutputFiles,
|
|
},
|
|
{
|
|
Widget: selectEncoder.SelectFileType,
|
|
},
|
|
{
|
|
Text: lang.L("selectFormat"),
|
|
Widget: selectEncoder.SelectFormat,
|
|
},
|
|
{
|
|
Text: lang.L("selectEncoder"),
|
|
Widget: selectEncoder.SelectEncoder,
|
|
},
|
|
}
|
|
formConvertor.form.Items = items
|
|
formConvertor.items = items
|
|
formConvertor.changeEncoder(selectEncoder.Encoder)
|
|
selectEncoder.ChangeEncoder = formConvertor.changeEncoder
|
|
|
|
formConvertor.form.OnSubmit = func() {
|
|
formConvertor.conversionMessage.Text = ""
|
|
if len(directoryForSavingButton.path) == 0 {
|
|
formConvertor.conversionMessage.Text = lang.L("errorSelectedFolderSave")
|
|
return
|
|
}
|
|
|
|
if len(selectEncoder.SelectFormat.Selected) == 0 {
|
|
formConvertor.conversionMessage.Text = lang.L("errorSelectedFormat")
|
|
return
|
|
}
|
|
|
|
if selectEncoder.Encoder == nil {
|
|
formConvertor.conversionMessage.Text = lang.L("errorSelectedEncoder")
|
|
return
|
|
}
|
|
|
|
fileForConversion.button.Disable()
|
|
directoryForSavingButton.button.Disable()
|
|
formConvertor.form.Disable()
|
|
|
|
fyne.Do(func() {
|
|
err := addToConversion(ConvertSetting{
|
|
DirectoryForSave: directoryForSavingButton.path,
|
|
OverwriteOutputFiles: isOverwriteOutputFiles,
|
|
Format: selectEncoder.SelectFormat.Selected,
|
|
Encoder: selectEncoder.Encoder,
|
|
})
|
|
if err != nil {
|
|
formConvertor.conversionMessage.Text = err.Error()
|
|
}
|
|
fileForConversion.button.Enable()
|
|
directoryForSavingButton.button.Enable()
|
|
formConvertor.form.Enable()
|
|
})
|
|
}
|
|
|
|
return formConvertor
|
|
}
|
|
|
|
func (f *formConvertor) getForm() fyne.CanvasObject {
|
|
return container.NewVBox(
|
|
f.form,
|
|
container.NewHScroll(f.conversionMessage),
|
|
)
|
|
}
|
|
|
|
type fileForConversion struct {
|
|
button *widget.Button
|
|
message *canvas.Text
|
|
file *ffmpeg.File
|
|
}
|
|
|
|
func (f *formConvertor) newFileForConversion() *fileForConversion {
|
|
message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
|
fileForConversion := &fileForConversion{
|
|
message: message,
|
|
}
|
|
|
|
buttonTitle := lang.L("choose") + "\n" +
|
|
lang.L("or") + "\n" +
|
|
lang.L("dragAndDropFiles")
|
|
|
|
var locationURI fyne.ListableURI
|
|
|
|
fileForConversion.button = widget.NewButton(buttonTitle, func() {
|
|
f.window.NewFileOpen(func(r fyne.URIReadCloser, err error) {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = ""
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
|
|
if err != nil {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = err.Error()
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
return
|
|
}
|
|
if r == nil {
|
|
return
|
|
}
|
|
|
|
f.addFileForConversion(ffmpeg.File{
|
|
Path: r.URI().Path(),
|
|
Name: r.URI().Name(),
|
|
Ext: r.URI().Extension(),
|
|
})
|
|
|
|
listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
|
|
locationURI, _ = storage.ListerForURI(listableURI)
|
|
}, locationURI)
|
|
})
|
|
|
|
f.window.SetOnDropped(func(position fyne.Position, uris []fyne.URI) {
|
|
if len(uris) == 0 {
|
|
return
|
|
}
|
|
|
|
isError := false
|
|
for _, uri := range uris {
|
|
info, err := os.Stat(uri.Path())
|
|
if err != nil {
|
|
isError = true
|
|
continue
|
|
}
|
|
if info.IsDir() {
|
|
isError = true
|
|
continue
|
|
}
|
|
|
|
f.addFileForConversion(ffmpeg.File{
|
|
Path: uri.Path(),
|
|
Name: uri.Name(),
|
|
Ext: uri.Extension(),
|
|
})
|
|
|
|
listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
|
|
locationURI, _ = storage.ListerForURI(listableURI)
|
|
}
|
|
|
|
if isError {
|
|
fileForConversion.message.Text = lang.L("errorDragAndDropFile")
|
|
utils.SetStringErrorStyle(fileForConversion.message)
|
|
} else {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = ""
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
}
|
|
})
|
|
|
|
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
|
|
}
|
|
|
|
type selectEncoder struct {
|
|
SelectFileType *widget.RadioGroup
|
|
SelectFormat *widget.Select
|
|
SelectEncoder *widget.Select
|
|
Encoder encoder2.EncoderContract
|
|
|
|
ChangeEncoder func(encoder encoder2.EncoderContract)
|
|
}
|
|
|
|
func (f *formConvertor) newSelectEncoder(formats encoder.ConvertorFormatsContract) *selectEncoder {
|
|
selectEncoder := &selectEncoder{}
|
|
|
|
encoderMap := map[int]encoder2.EncoderDataContract{}
|
|
selectEncoder.SelectEncoder = widget.NewSelect([]string{}, func(s string) {
|
|
if encoderMap[selectEncoder.SelectEncoder.SelectedIndex()] == nil {
|
|
return
|
|
}
|
|
selectEncoderData := encoderMap[selectEncoder.SelectEncoder.SelectedIndex()]
|
|
selectEncoder.Encoder = selectEncoderData.NewEncoder()
|
|
if selectEncoder.ChangeEncoder != nil {
|
|
selectEncoder.ChangeEncoder(selectEncoder.Encoder)
|
|
}
|
|
})
|
|
|
|
formatSelected := ""
|
|
selectEncoder.SelectFormat = widget.NewSelect([]string{}, func(s string) {
|
|
if formatSelected == s {
|
|
return
|
|
}
|
|
formatSelected = s
|
|
format, err := formats.GetFormat(s)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var encoderOptions []string
|
|
encoderMap = map[int]encoder2.EncoderDataContract{}
|
|
for _, e := range format.GetEncoders() {
|
|
encoderMap[len(encoderMap)] = e
|
|
encoderOptions = append(encoderOptions, lang.L("encoder_"+e.GetTitle()))
|
|
}
|
|
selectEncoder.SelectEncoder.SetOptions(encoderOptions)
|
|
selectEncoder.SelectEncoder.SetSelectedIndex(0)
|
|
})
|
|
|
|
var fileTypeOptions []string
|
|
for _, fileType := range encoder2.GetListFileType() {
|
|
fileTypeOptions = append(fileTypeOptions, fileType.Name())
|
|
}
|
|
|
|
encoderGroupVideo := lang.L("encoderGroupVideo")
|
|
encoderGroupAudio := lang.L("encoderGroupAudio")
|
|
encoderGroupImage := lang.L("encoderGroupImage")
|
|
encoderGroup := map[string]string{
|
|
encoderGroupVideo: "video",
|
|
encoderGroupAudio: "audio",
|
|
encoderGroupImage: "image",
|
|
}
|
|
selectEncoder.SelectFileType = widget.NewRadioGroup([]string{encoderGroupVideo, encoderGroupAudio, encoderGroupImage}, func(s string) {
|
|
groupCode := encoderGroup[s]
|
|
|
|
var formatOptions []string
|
|
for _, f := range formats.GetFormats() {
|
|
if groupCode != f.GetFileType().Name() {
|
|
continue
|
|
}
|
|
formatOptions = append(formatOptions, f.GetTitle())
|
|
}
|
|
selectEncoder.SelectFormat.SetOptions(formatOptions)
|
|
if groupCode == encoder2.FileType(encoder2.Video).Name() {
|
|
selectEncoder.SelectFormat.SetSelected("mp4")
|
|
} else {
|
|
selectEncoder.SelectFormat.SetSelectedIndex(0)
|
|
}
|
|
})
|
|
selectEncoder.SelectFileType.Horizontal = true
|
|
selectEncoder.SelectFileType.Required = true
|
|
selectEncoder.SelectFileType.SetSelected(encoderGroupVideo)
|
|
|
|
return selectEncoder
|
|
}
|
|
|
|
func (f *formConvertor) changeEncoder(encoder encoder2.EncoderContract) {
|
|
var items []*widget.FormItem
|
|
|
|
if encoders.Views[encoder.GetName()] != nil {
|
|
items = encoders.Views[encoder.GetName()](encoder)
|
|
}
|
|
|
|
f.changeItems(items)
|
|
}
|
|
|
|
func (f *formConvertor) changeItems(items []*widget.FormItem) {
|
|
fyne.Do(func() {
|
|
f.form.Items = f.items
|
|
f.form.Refresh()
|
|
f.form.Items = append(f.form.Items, items...)
|
|
f.form.Refresh()
|
|
})
|
|
}
|