Compare commits

..

No commits in common. "main" and "0.8.0" have entirely different histories.
main ... 0.8.0

29 changed files with 294 additions and 1781 deletions

View File

@ -2,7 +2,7 @@
Icon = "icon.png" Icon = "icon.png"
Name = "GUI for FFmpeg" Name = "GUI for FFmpeg"
ID = "net.kor-elf.projects.gui-for-ffmpeg" ID = "net.kor-elf.projects.gui-for-ffmpeg"
Version = "0.9.0" Version = "0.8.0"
Build = 4 Build = 4
[Migrations] [Migrations]

View File

@ -9,8 +9,6 @@ type RepositoryContract interface {
SavePathFfmpeg(code string) (setting.Setting, error) SavePathFfmpeg(code string) (setting.Setting, error)
GetPathFfprobe() (string, error) GetPathFfprobe() (string, error)
SavePathFfprobe(code string) (setting.Setting, error) SavePathFfprobe(code string) (setting.Setting, error)
GetPathFfplay() (string, error)
SavePathFfplay(code string) (setting.Setting, error)
} }
type Repository struct { type Repository struct {
@ -36,11 +34,3 @@ func (r Repository) GetPathFfprobe() (string, error) {
func (r Repository) SavePathFfprobe(path string) (setting.Setting, error) { func (r Repository) SavePathFfprobe(path string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("ffprobe", path) return r.settingRepository.CreateOrUpdate("ffprobe", path)
} }
func (r Repository) GetPathFfplay() (string, error) {
return r.settingRepository.GetValue("ffplay")
}
func (r Repository) SavePathFfplay(path string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("ffplay", path)
}

View File

@ -18,8 +18,7 @@ type ViewContract interface {
SelectFFPath( SelectFFPath(
ffmpegPath string, ffmpegPath string,
ffprobePath string, ffprobePath string,
ffplayPath string, save func(ffmpegPath string, ffprobePath string) error,
save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
cancel func(), cancel func(),
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error, donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
) )

View File

@ -32,22 +32,22 @@ type Conversion struct {
overwriteOutputFiles *overwriteOutputFiles overwriteOutputFiles *overwriteOutputFiles
selectEncoder *selectEncoder selectEncoder *selectEncoder
runConvert func(setting HandleConvertSetting) runConvert func(setting HandleConvertSetting)
itemsToConvertService kernel.ItemsToConvertContract
} }
type HandleConvertSetting struct { type HandleConvertSetting struct {
FileInput kernel.File
DirectoryForSave string DirectoryForSave string
OverwriteOutputFiles bool OverwriteOutputFiles bool
Format string Format string
Encoder encoder2.EncoderContract Encoder encoder2.EncoderContract
} }
func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContract, runConvert func(setting HandleConvertSetting), settingDirectoryForSaving setting.DirectoryForSavingContract, itemsToConvertService kernel.ItemsToConvertContract) *Conversion { func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContract, runConvert func(setting HandleConvertSetting), settingDirectoryForSaving setting.DirectoryForSavingContract) *Conversion {
conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255}) conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
conversionMessage.TextSize = 16 conversionMessage.TextSize = 16
conversionMessage.TextStyle = fyne.TextStyle{Bold: true} conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
fileForConversion := newFileForConversion(app, itemsToConvertService) fileForConversion := newFileForConversion(app)
directoryForSaving := newDirectoryForSaving(app, settingDirectoryForSaving) directoryForSaving := newDirectoryForSaving(app, settingDirectoryForSaving)
overwriteOutputFiles := newOverwriteOutputFiles(app) overwriteOutputFiles := newOverwriteOutputFiles(app)
selectEncoder := newSelectEncoder(app, formats) selectEncoder := newSelectEncoder(app, formats)
@ -93,7 +93,6 @@ func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContr
overwriteOutputFiles: overwriteOutputFiles, overwriteOutputFiles: overwriteOutputFiles,
selectEncoder: selectEncoder, selectEncoder: selectEncoder,
runConvert: runConvert, runConvert: runConvert,
itemsToConvertService: itemsToConvertService,
} }
} }
@ -122,32 +121,20 @@ func (c Conversion) changeEncoder(encoder encoder2.EncoderContract) {
} }
func (c Conversion) AfterViewContent() { func (c Conversion) AfterViewContent() {
if len(c.itemsToConvertService.GetItems()) == 0 {
c.form.form.Disable() c.form.form.Disable()
} }
}
func (c Conversion) selectFileForConversion(err error) { func (c Conversion) selectFileForConversion(err error) {
c.conversionMessage.Text = "" c.conversionMessage.Text = ""
if len(c.itemsToConvertService.GetItems()) == 0 {
if err != nil { if err != nil {
c.form.form.Disable() c.form.form.Disable()
return return
} }
}
c.form.form.Enable() c.form.form.Enable()
} }
func (c Conversion) submit() { func (c Conversion) submit() {
if len(c.itemsToConvertService.GetItems()) == 0 {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorNoFilesAddedForConversion",
})))
c.enableFormConversion()
return
}
if len(c.directoryForSaving.path) == 0 { if len(c.directoryForSaving.path) == 0 {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorSelectedFolderSave", MessageID: "errorSelectedFolderSave",
@ -173,18 +160,19 @@ func (c Conversion) submit() {
c.directoryForSaving.button.Disable() c.directoryForSaving.button.Disable()
c.form.form.Disable() c.form.form.Disable()
c.runConvert(HandleConvertSetting{ setting := HandleConvertSetting{
FileInput: *c.fileForConversion.file,
DirectoryForSave: c.directoryForSaving.path, DirectoryForSave: c.directoryForSaving.path,
OverwriteOutputFiles: c.overwriteOutputFiles.IsChecked(), OverwriteOutputFiles: c.overwriteOutputFiles.IsChecked(),
Format: c.selectEncoder.SelectFormat.Selected, Format: c.selectEncoder.SelectFormat.Selected,
Encoder: c.selectEncoder.Encoder, Encoder: c.selectEncoder.Encoder,
}) }
c.runConvert(setting)
c.enableFormConversion() c.enableFormConversion()
if len(c.itemsToConvertService.GetItems()) == 0 { c.fileForConversion.message.Text = ""
c.form.form.Disable() c.form.form.Disable()
} }
}
func (c Conversion) enableFormConversion() { func (c Conversion) enableFormConversion() {
c.fileForConversion.button.Enable() c.fileForConversion.button.Enable()
@ -200,49 +188,44 @@ type fileForConversion struct {
changeCallbacks map[int]func(err error) changeCallbacks map[int]func(err error)
} }
func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.ItemsToConvertContract) *fileForConversion { func newFileForConversion(app kernel.AppContract) *fileForConversion {
message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
fileForConversion := &fileForConversion{ fileForConversion := &fileForConversion{
message: message, file: &kernel.File{},
changeCallbacks: map[int]func(err error){}, changeCallbacks: map[int]func(err error){},
} }
buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "choose", MessageID: "choose",
}) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ }) + "\n\r\n\r" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "or", MessageID: "or",
}) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ }) + "\n\r\n\r" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "dragAndDropFiles", MessageID: "dragAndDrop1File",
}) })
fileForConversion.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
fileForConversion.message.TextSize = 16
fileForConversion.message.TextStyle = fyne.TextStyle{Bold: true}
var locationURI fyne.ListableURI var locationURI fyne.ListableURI
fileForConversion.button = widget.NewButton(buttonTitle, func() { fileForConversion.button = widget.NewButton(buttonTitle, func() {
app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) { app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
fyne.Do(func() {
fileForConversion.message.Text = ""
fileForConversion.message.Refresh()
})
if err != nil { if err != nil {
fyne.Do(func() {
fileForConversion.message.Text = err.Error() fileForConversion.message.Text = err.Error()
fileForConversion.message.Refresh() setStringErrorStyle(fileForConversion.message)
})
fileForConversion.eventSelectFile(err) fileForConversion.eventSelectFile(err)
return return
} }
if r == nil { if r == nil {
return return
} }
app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
itemsToConvertService.Add(&kernel.File{ fileForConversion.file.Path = r.URI().Path()
Path: r.URI().Path(), fileForConversion.file.Name = r.URI().Name()
Name: r.URI().Name(), fileForConversion.file.Ext = r.URI().Extension()
Ext: r.URI().Extension(),
}) fileForConversion.message.Text = r.URI().Path()
setStringSuccessStyle(fileForConversion.message)
fileForConversion.eventSelectFile(nil) fileForConversion.eventSelectFile(nil)
@ -256,42 +239,43 @@ func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.I
return return
} }
isError := false if len(uris) > 1 {
for _, uri := range uris { fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
info, err := os.Stat(uri.Path()) MessageID: "errorDragAndDrop1File",
if err != nil { })
isError = true setStringErrorStyle(fileForConversion.message)
continue fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
} return
if info.IsDir() {
isError = true
continue
} }
itemsToConvertService.Add(&kernel.File{ uri := uris[0]
Path: uri.Path(), info, err := os.Stat(uri.Path())
Name: uri.Name(), if err != nil {
Ext: uri.Extension(), fileForConversion.message.Text = err.Error()
setStringErrorStyle(fileForConversion.message)
fileForConversion.eventSelectFile(err)
return
}
if info.IsDir() {
fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorIsFolder",
}) })
setStringErrorStyle(fileForConversion.message)
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
return
}
fileForConversion.file.Path = uri.Path()
fileForConversion.file.Name = uri.Name()
fileForConversion.file.Ext = uri.Extension()
fileForConversion.message.Text = uri.Path()
setStringSuccessStyle(fileForConversion.message)
fileForConversion.eventSelectFile(nil) fileForConversion.eventSelectFile(nil)
listableURI := storage.NewFileURI(filepath.Dir(uri.Path())) listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
locationURI, _ = storage.ListerForURI(listableURI) locationURI, _ = storage.ListerForURI(listableURI)
}
app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
if isError {
fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorDragAndDropFile",
})
setStringErrorStyle(fileForConversion.message)
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
} else {
fyne.Do(func() {
fileForConversion.message.Text = ""
fileForConversion.message.Refresh()
})
}
}) })
return fileForConversion return fileForConversion

View File

@ -15,8 +15,7 @@ import (
func (v View) SelectFFPath( func (v View) SelectFFPath(
currentPathFfmpeg string, currentPathFfmpeg string,
currentPathFfprobe string, currentPathFfprobe string,
currentPathFfplay string, save func(ffmpegPath string, ffprobePath string) error,
save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
cancel func(), cancel func(),
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error, donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
) { ) {
@ -26,7 +25,6 @@ func (v View) SelectFFPath(
ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile(currentPathFfmpeg) ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile(currentPathFfmpeg)
ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile(currentPathFfprobe) ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile(currentPathFfprobe)
ffplayPath, buttonFFplay, buttonFFplayMessage := v.getButtonSelectFile(currentPathFfplay)
link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{ link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
Scheme: "https", Scheme: "https",
@ -60,15 +58,6 @@ func (v View) SelectFFPath(
{ {
Widget: container.NewHScroll(buttonFFprobeMessage), Widget: container.NewHScroll(buttonFFprobeMessage),
}, },
{
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "pathToFfplay",
}),
Widget: buttonFFplay,
},
{
Widget: container.NewHScroll(buttonFFplayMessage),
},
{ {
Widget: errorMessage, Widget: errorMessage,
}, },
@ -77,7 +66,7 @@ func (v View) SelectFFPath(
MessageID: "save", MessageID: "save",
}), }),
OnSubmit: func() { OnSubmit: func() {
err := save(*ffmpegPath, *ffprobePath, *ffplayPath) err := save(*ffmpegPath, *ffprobePath)
if err != nil { if err != nil {
errorMessage.Text = err.Error() errorMessage.Text = err.Error()
} }

View File

@ -1,14 +1,11 @@
package error package error
import ( import (
"errors"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"go.etcd.io/bbolt"
) )
type ViewContract interface { type ViewContract interface {
@ -17,37 +14,23 @@ type ViewContract interface {
type View struct { type View struct {
app kernel.AppContract app kernel.AppContract
isSetLanguage bool
} }
func NewView(app kernel.AppContract) *View { func NewView(app kernel.AppContract) *View {
return &View{ return &View{
app: app, app: app,
isSetLanguage: true,
} }
} }
func (v View) PanicError(err error) { func (v View) PanicError(err error) {
if v.isSetLanguage {
v.isSetLanguage = false
_ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
}
messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "error", MessageID: "error",
}) })
messagetText := err.Error()
if errors.Is(err, bbolt.ErrTimeout) {
messagetText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorDatabaseTimeout",
})
}
v.app.GetWindow().SetContent(container.NewBorder( v.app.GetWindow().SetContent(container.NewBorder(
container.NewVBox( container.NewVBox(
widget.NewLabel(messageHead), widget.NewLabel(messageHead),
widget.NewLabel(messagetText), widget.NewLabel(err.Error()),
), ),
nil, nil,
nil, nil,
@ -59,11 +42,6 @@ func (v View) PanicError(err error) {
} }
func (v View) PanicErrorWriteDirectoryData() { func (v View) PanicErrorWriteDirectoryData() {
if v.isSetLanguage {
v.isSetLanguage = false
_ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
}
message := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ message := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorDatabase", MessageID: "errorDatabase",
}) })

View File

@ -16,7 +16,6 @@ type ConvertorHandlerContract interface {
FfPathSelection() FfPathSelection()
GetFfmpegVersion() (string, error) GetFfmpegVersion() (string, error)
GetFfprobeVersion() (string, error) GetFfprobeVersion() (string, error)
GetFfplayVersion() (string, error)
} }
type ConvertorHandler struct { type ConvertorHandler struct {
@ -25,7 +24,6 @@ type ConvertorHandler struct {
errorView error2.ViewContract errorView error2.ViewContract
convertorRepository convertor.RepositoryContract convertorRepository convertor.RepositoryContract
settingDirectoryForSaving setting.DirectoryForSavingContract settingDirectoryForSaving setting.DirectoryForSavingContract
itemsToConvertService kernel.ItemsToConvertContract
} }
func NewConvertorHandler( func NewConvertorHandler(
@ -34,7 +32,6 @@ func NewConvertorHandler(
errorView error2.ViewContract, errorView error2.ViewContract,
convertorRepository convertor.RepositoryContract, convertorRepository convertor.RepositoryContract,
settingDirectoryForSaving setting.DirectoryForSavingContract, settingDirectoryForSaving setting.DirectoryForSavingContract,
itemsToConvertService kernel.ItemsToConvertContract,
) *ConvertorHandler { ) *ConvertorHandler {
return &ConvertorHandler{ return &ConvertorHandler{
app: app, app: app,
@ -42,7 +39,6 @@ func NewConvertorHandler(
errorView: errorView, errorView: errorView,
convertorRepository: convertorRepository, convertorRepository: convertorRepository,
settingDirectoryForSaving: settingDirectoryForSaving, settingDirectoryForSaving: settingDirectoryForSaving,
itemsToConvertService: itemsToConvertService,
} }
} }
@ -53,18 +49,17 @@ func (h ConvertorHandler) MainConvertor() {
h.errorView.PanicError(err) h.errorView.PanicError(err)
return return
} }
conversion := view.NewConversion(h.app, formats, h.runConvert, h.settingDirectoryForSaving, h.itemsToConvertService) conversion := view.NewConversion(h.app, formats, h.runConvert, h.settingDirectoryForSaving)
h.convertorView.Main(conversion) h.convertorView.Main(conversion)
return return
} }
h.convertorView.SelectFFPath("", "", "", h.saveSettingFFPath, nil, h.downloadFFmpeg) h.convertorView.SelectFFPath("", "", h.saveSettingFFPath, nil, h.downloadFFmpeg)
} }
func (h ConvertorHandler) FfPathSelection() { func (h ConvertorHandler) FfPathSelection() {
ffmpeg, _ := h.convertorRepository.GetPathFfmpeg() ffmpeg, _ := h.convertorRepository.GetPathFfmpeg()
ffprobe, _ := h.convertorRepository.GetPathFfprobe() ffprobe, _ := h.convertorRepository.GetPathFfprobe()
ffplay, _ := h.convertorRepository.GetPathFfplay() h.convertorView.SelectFFPath(ffmpeg, ffprobe, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
h.convertorView.SelectFFPath(ffmpeg, ffprobe, ffplay, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
} }
func (h ConvertorHandler) GetFfmpegVersion() (string, error) { func (h ConvertorHandler) GetFfmpegVersion() (string, error) {
@ -75,32 +70,18 @@ func (h ConvertorHandler) GetFfprobeVersion() (string, error) {
return h.app.GetConvertorService().GetFFprobeVersion() return h.app.GetConvertorService().GetFFprobeVersion()
} }
func (h ConvertorHandler) GetFfplayVersion() (string, error) {
return h.app.GetConvertorService().GetFFplayVersion()
}
func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) { func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
h.app.GetWindow().GetLayout().GetRightTabs().SelectFileQueueTab()
for _, item := range h.itemsToConvertService.GetItems() {
file := item.GetFile()
if file == nil {
continue
}
h.app.GetQueue().Add(&kernel.ConvertSetting{ h.app.GetQueue().Add(&kernel.ConvertSetting{
VideoFileInput: *file, VideoFileInput: setting.FileInput,
VideoFileOut: kernel.File{ VideoFileOut: kernel.File{
Path: setting.DirectoryForSave + helper.PathSeparator() + file.Name + "." + setting.Format, Path: setting.DirectoryForSave + helper.PathSeparator() + setting.FileInput.Name + "." + setting.Format,
Name: file.Name, Name: setting.FileInput.Name,
Ext: "." + setting.Format, Ext: "." + setting.Format,
}, },
OverwriteOutputFiles: setting.OverwriteOutputFiles, OverwriteOutputFiles: setting.OverwriteOutputFiles,
Encoder: setting.Encoder, Encoder: setting.Encoder,
}) })
} }
h.itemsToConvertService.AfterAddingQueue()
}
func (h ConvertorHandler) checkingFFPathUtilities() bool { func (h ConvertorHandler) checkingFFPathUtilities() bool {
if h.checkingFFPath() == true { if h.checkingFFPath() == true {
@ -117,21 +98,15 @@ func (h ConvertorHandler) checkingFFPathUtilities() bool {
if ffprobeChecking == false { if ffprobeChecking == false {
continue continue
} }
ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(item.FFplay)
if ffplayChecking == false {
continue
}
_, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg) _, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg)
_, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe) _, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe)
_, _ = h.convertorRepository.SavePathFfplay(item.FFplay)
return true return true
} }
return false return false
} }
func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string, ffplayPath string) error { func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string) error {
ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(ffmpegPath) ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(ffmpegPath)
if ffmpegChecking == false { if ffmpegChecking == false {
errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
@ -148,17 +123,8 @@ func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath strin
return errors.New(errorText) return errors.New(errorText)
} }
ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(ffplayPath)
if ffplayChecking == false {
errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFplay",
})
return errors.New(errorText)
}
_, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath) _, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath)
_, _ = h.convertorRepository.SavePathFfprobe(ffprobePath) _, _ = h.convertorRepository.SavePathFfprobe(ffprobePath)
_, _ = h.convertorRepository.SavePathFfplay(ffplayPath)
h.MainConvertor() h.MainConvertor()
@ -176,10 +142,5 @@ func (h ConvertorHandler) checkingFFPath() bool {
return false return false
} }
_, err = h.app.GetConvertorService().GetFFplayVersion()
if err != nil {
return false
}
return true return true
} }

View File

@ -10,7 +10,7 @@ import (
) )
func getPathsToFF() []kernel.FFPathUtilities { func getPathsToFF() []kernel.FFPathUtilities {
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}} return []kernel.FFPathUtilities{{"ffmpeg/bin/ffmpeg", "ffmpeg/bin/ffprobe"}, {"ffmpeg", "ffprobe"}}
} }
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) { func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {

View File

@ -19,7 +19,7 @@ import (
) )
func getPathsToFF() []kernel.FFPathUtilities { func getPathsToFF() []kernel.FFPathUtilities {
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}} return []kernel.FFPathUtilities{{"ffmpeg/bin/ffmpeg", "ffmpeg/bin/ffprobe"}, {"ffmpeg", "ffprobe"}}
} }
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) { func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
@ -60,11 +60,7 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
progressMessage.Refresh() progressMessage.Refresh()
}) })
err = h.saveSettingFFPath( err = h.saveSettingFFPath("ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg", "ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffprobe")
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg",
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffprobe",
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffplay",
)
if err != nil { if err != nil {
return err return err
} }
@ -221,12 +217,6 @@ func unTarXz(fileTar string, directory string, progressBar *widget.ProgressBar)
return err return err
} }
ffplayPath := filepath.Join(directory, "ffmpeg-master-latest-linux64-gpl", "bin", "ffplay")
err = os.Chmod(ffplayPath, 0755)
if err != nil {
return err
}
return nil return nil
} }

View File

@ -19,7 +19,7 @@ import (
) )
func getPathsToFF() []kernel.FFPathUtilities { func getPathsToFF() []kernel.FFPathUtilities {
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg\\bin\\ffmpeg.exe", FFprobe: "ffmpeg\\bin\\ffprobe.exe", FFplay: "ffmpeg\\bin\\ffplay.exe"}} return []kernel.FFPathUtilities{{"ffmpeg\\bin\\ffmpeg.exe", "ffmpeg\\bin\\ffprobe.exe"}}
} }
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) { func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
@ -59,11 +59,7 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
err = h.saveSettingFFPath( err = h.saveSettingFFPath("ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe", "ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe")
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe",
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe",
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffplay.exe",
)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,7 +1,6 @@
package handler package handler
import ( import (
"fyne.io/fyne/v2/lang"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
) )
@ -29,13 +28,10 @@ func NewMainHandler(
func (h MainHandler) Start() { func (h MainHandler) Start() {
language, err := h.localizerRepository.GetCode() language, err := h.localizerRepository.GetCode()
if err != nil {
err = h.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
if err != nil { if err != nil {
h.menuHandler.LanguageSelection() h.menuHandler.LanguageSelection()
return return
} }
}
_ = h.app.GetLocalizerService().SetCurrentLanguageByCode(language) _ = h.app.GetLocalizerService().SetCurrentLanguageByCode(language)
h.convertorHandler.MainConvertor() h.convertorHandler.MainConvertor()

View File

@ -5,7 +5,6 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/menu" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/menu"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
) )
@ -18,29 +17,23 @@ type MenuHandler struct {
app kernel.AppContract app kernel.AppContract
convertorHandler ConvertorHandlerContract convertorHandler ConvertorHandlerContract
menuView menu.ViewContract menuView menu.ViewContract
menuViewSetting menu.ViewSettingContract
localizerView localizer.ViewContract localizerView localizer.ViewContract
localizerRepository localizer.RepositoryContract localizerRepository localizer.RepositoryContract
themeService theme.ThemeContract
} }
func NewMenuHandler( func NewMenuHandler(
app kernel.AppContract, app kernel.AppContract,
convertorHandler ConvertorHandlerContract, convertorHandler ConvertorHandlerContract,
menuView menu.ViewContract, menuView menu.ViewContract,
menuViewSetting menu.ViewSettingContract,
localizerView localizer.ViewContract, localizerView localizer.ViewContract,
localizerRepository localizer.RepositoryContract, localizerRepository localizer.RepositoryContract,
themeService theme.ThemeContract,
) *MenuHandler { ) *MenuHandler {
return &MenuHandler{ return &MenuHandler{
app: app, app: app,
convertorHandler: convertorHandler, convertorHandler: convertorHandler,
menuView: menuView, menuView: menuView,
menuViewSetting: menuViewSetting,
localizerView: localizerView, localizerView: localizerView,
localizerRepository: localizerRepository, localizerRepository: localizerRepository,
themeService: themeService,
} }
} }
@ -60,11 +53,11 @@ func (h MenuHandler) getMenuSettings() *fyne.Menu {
quit.Label = text quit.Label = text
}) })
settingsSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ languageSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings", MessageID: "changeLanguage",
}), h.settingsSelection) }), h.LanguageSelection)
h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) { h.app.GetLocalizerService().AddChangeCallback("changeLanguage", func(text string) {
settingsSelection.Label = text languageSelection.Label = text
}) })
ffPathSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ ffPathSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
@ -76,7 +69,7 @@ func (h MenuHandler) getMenuSettings() *fyne.Menu {
settings := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ settings := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings", MessageID: "settings",
}), settingsSelection, ffPathSelection, quit) }), languageSelection, ffPathSelection, quit)
h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) { h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) {
settings.Label = text settings.Label = text
settings.Refresh() settings.Refresh()
@ -95,21 +88,14 @@ func (h MenuHandler) getMenuHelp() *fyne.Menu {
gratitude := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ gratitude := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "gratitude", MessageID: "gratitude",
}), h.menuView.Gratitude) }), h.openGratitude)
h.app.GetLocalizerService().AddChangeCallback("gratitude", func(text string) { h.app.GetLocalizerService().AddChangeCallback("gratitude", func(text string) {
gratitude.Label = text gratitude.Label = text
}) })
helpFFplay := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplay",
}), h.menuView.HelpFFplay)
h.app.GetLocalizerService().AddChangeCallback("helpFFplay", func(text string) {
helpFFplay.Label = text
})
help := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ help := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "help", MessageID: "help",
}), helpFFplay, about, gratitude) }), about, gratitude)
h.app.GetLocalizerService().AddChangeCallback("help", func(text string) { h.app.GetLocalizerService().AddChangeCallback("help", func(text string) {
help.Label = text help.Label = text
help.Refresh() help.Refresh()
@ -131,14 +117,12 @@ func (h MenuHandler) openAbout() {
MessageID: "errorFFprobeVersion", MessageID: "errorFFprobeVersion",
}) })
} }
ffplay, err := h.convertorHandler.GetFfplayVersion()
if err != nil { h.menuView.About(ffmpeg, ffprobe)
ffplay = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFplayVersion",
})
} }
h.menuView.About(ffmpeg, ffprobe, ffplay) func (h MenuHandler) openGratitude() {
h.menuView.Gratitude()
} }
func (h MenuHandler) LanguageSelection() { func (h MenuHandler) LanguageSelection() {
@ -147,28 +131,3 @@ func (h MenuHandler) LanguageSelection() {
h.convertorHandler.MainConvertor() h.convertorHandler.MainConvertor()
}) })
} }
func (h MenuHandler) settingsSelection() {
save := func(setting *menu.SettingForm) error {
err := h.app.GetLocalizerService().SetCurrentLanguage(setting.Language)
if err != nil {
return err
}
_, err = h.localizerRepository.Save(setting.Language.Code)
if err != nil {
return err
}
err = h.themeService.SetCurrentTheme(setting.ThemeInfo)
if err != nil {
return err
}
h.convertorHandler.MainConvertor()
return nil
}
cancel := func() {
h.convertorHandler.MainConvertor()
}
h.menuViewSetting.Main(save, cancel)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -12,7 +12,6 @@ type AppContract interface {
GetQueue() QueueListContract GetQueue() QueueListContract
GetLocalizerService() LocalizerContract GetLocalizerService() LocalizerContract
GetConvertorService() ConvertorContract GetConvertorService() ConvertorContract
GetFFplayService() FFplayContract
AfterClosing() AfterClosing()
RunConvertor() RunConvertor()
} }
@ -24,34 +23,25 @@ type App struct {
localizerService LocalizerContract localizerService LocalizerContract
convertorService ConvertorContract convertorService ConvertorContract
blockProgressbarService BlockProgressbarContract
ffplayService FFplayContract
} }
func NewApp( func NewApp(
metadata *fyne.AppMetadata, metadata *fyne.AppMetadata,
localizerService LocalizerContract, localizerService LocalizerContract,
queue QueueListContract, queue QueueListContract,
ffplayService FFplayContract, queueLayoutObject QueueLayoutObjectContract,
convertorService ConvertorContract, convertorService ConvertorContract,
) *App { ) *App {
app.SetMetadata(*metadata) app.SetMetadata(*metadata)
a := app.New() a := app.New()
statusesText := GetBlockProgressbarStatusesText(localizerService)
blockProgressbarService := NewBlockProgressbar(statusesText, ffplayService)
rightTabsService := NewRightTabs(localizerService)
queueLayoutObject := NewQueueLayoutObject(queue, localizerService, ffplayService, rightTabsService, blockProgressbarService.GetContainer())
return &App{ return &App{
AppFyne: a, AppFyne: a,
Window: newWindow(a.NewWindow("GUI for FFmpeg"), NewLayout(queueLayoutObject, localizerService, rightTabsService)), Window: newWindow(a.NewWindow("GUI for FFmpeg"), NewLayout(queueLayoutObject, localizerService)),
Queue: queue, Queue: queue,
localizerService: localizerService, localizerService: localizerService,
convertorService: convertorService, convertorService: convertorService,
blockProgressbarService: blockProgressbarService,
ffplayService: ffplayService,
} }
} }
@ -75,10 +65,6 @@ func (a App) GetConvertorService() ConvertorContract {
return a.convertorService return a.convertorService
} }
func (a App) GetFFplayService() FFplayContract {
return a.ffplayService
}
func (a App) AfterClosing() { func (a App) AfterClosing() {
for _, cmd := range a.convertorService.GetRunningProcesses() { for _, cmd := range a.convertorService.GetRunningProcesses() {
_ = cmd.Process.Kill() _ = cmd.Process.Kill()
@ -95,33 +81,22 @@ func (a App) RunConvertor() {
} }
queue.Status = StatusType(InProgress) queue.Status = StatusType(InProgress)
a.Window.GetLayout().ChangeQueueStatus(queueId, queue) a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
if a.blockProgressbarService.GetContainer().Hidden {
a.blockProgressbarService.GetContainer().Show()
}
totalDuration, err := a.convertorService.GetTotalDuration(&queue.Setting.VideoFileInput) totalDuration, err := a.convertorService.GetTotalDuration(&queue.Setting.VideoFileInput)
if err != nil { if err != nil {
totalDuration = 0 totalDuration = 0
} }
progress := a.Window.GetLayout().NewProgressbar(queueId, totalDuration)
progress := a.blockProgressbarService.GetProgressbar(
totalDuration,
queue.Setting.VideoFileInput.Path,
a.localizerService,
)
err = a.convertorService.RunConvert(*queue.Setting, progress) err = a.convertorService.RunConvert(*queue.Setting, progress)
if err != nil { if err != nil {
queue.Status = StatusType(Error) queue.Status = StatusType(Error)
queue.Error = err queue.Error = err
a.Window.GetLayout().ChangeQueueStatus(queueId, queue) a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
a.blockProgressbarService.ProcessEndedWithError(err.Error())
continue continue
} }
queue.Status = StatusType(Completed) queue.Status = StatusType(Completed)
a.Window.GetLayout().ChangeQueueStatus(queueId, queue) a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
a.blockProgressbarService.ProcessEndedWithSuccess(queue.Setting.VideoFileOut.Path)
} }
}() }()
} }

View File

@ -32,10 +32,8 @@ type ConvertorContract interface {
GetTotalDuration(file *File) (float64, error) GetTotalDuration(file *File) (float64, error)
GetFFmpegVesrion() (string, error) GetFFmpegVesrion() (string, error)
GetFFprobeVersion() (string, error) GetFFprobeVersion() (string, error)
GetFFplayVersion() (string, error)
ChangeFFmpegPath(path string) (bool, error) ChangeFFmpegPath(path string) (bool, error)
ChangeFFprobePath(path string) (bool, error) ChangeFFprobePath(path string) (bool, error)
ChangeFFplayPath(path string) (bool, error)
GetRunningProcesses() map[int]*exec.Cmd GetRunningProcesses() map[int]*exec.Cmd
GetSupportFormats() (encoder.ConvertorFormatsContract, error) GetSupportFormats() (encoder.ConvertorFormatsContract, error)
} }
@ -48,7 +46,6 @@ type ProgressContract interface {
type FFPathUtilities struct { type FFPathUtilities struct {
FFmpeg string FFmpeg string
FFprobe string FFprobe string
FFplay string
} }
type runningProcesses struct { type runningProcesses struct {
@ -180,17 +177,6 @@ func (s Convertor) GetFFprobeVersion() (string, error) {
return text[0], nil return text[0], nil
} }
func (s Convertor) GetFFplayVersion() (string, error) {
cmd := exec.Command(s.ffPathUtilities.FFplay, "-version")
helper.PrepareBackgroundCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
return text[0], nil
}
func (s Convertor) ChangeFFmpegPath(path string) (bool, error) { func (s Convertor) ChangeFFmpegPath(path string) (bool, error) {
cmd := exec.Command(path, "-version") cmd := exec.Command(path, "-version")
helper.PrepareBackgroundCommand(cmd) helper.PrepareBackgroundCommand(cmd)
@ -219,20 +205,6 @@ func (s Convertor) ChangeFFprobePath(path string) (bool, error) {
return true, nil return true, nil
} }
func (s Convertor) ChangeFFplayPath(path string) (bool, error) {
cmd := exec.Command(path, "-version")
helper.PrepareBackgroundCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
return false, err
}
if strings.Contains(strings.TrimSpace(string(out)), "ffplay") == false {
return false, nil
}
s.ffPathUtilities.FFplay = path
return true, nil
}
func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) { func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
formats := encoder.NewConvertorFormats() formats := encoder.NewConvertorFormats()
cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders") cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders")

View File

@ -1,28 +0,0 @@
package kernel
import (
"os/exec"
)
type FFplay struct {
ffPathUtilities *FFPathUtilities
}
type FFplaySetting struct {
PathToFile string
}
type FFplayContract interface {
Run(setting FFplaySetting) error
}
func NewFFplay(ffPathUtilities *FFPathUtilities) *FFplay {
return &FFplay{ffPathUtilities: ffPathUtilities}
}
func (ffplay FFplay) Run(setting FFplaySetting) error {
args := []string{setting.PathToFile}
cmd := exec.Command(ffplay.ffPathUtilities.FFplay, args...)
return cmd.Start()
}

View File

@ -1,151 +0,0 @@
package kernel
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
)
type ItemsToConvertContract interface {
Add(file *File)
GetItems() map[int]ItemToConvertContract
AfterAddingQueue()
}
type ItemsToConvert struct {
nextId int
items map[int]ItemToConvertContract
itemsContainer *fyne.Container
ffplayService FFplayContract
isAutoRemove bool
}
func NewItemsToConvert(itemsContainer *fyne.Container, ffplayService FFplayContract, localizerService LocalizerContract) *ItemsToConvert {
containerForItems := container.NewVBox()
ItemsToConvert := &ItemsToConvert{
nextId: 0,
items: map[int]ItemToConvertContract{},
itemsContainer: containerForItems,
ffplayService: ffplayService,
isAutoRemove: true,
}
line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
line.StrokeWidth = 5
checkboxAutoRemove := widget.NewCheck(localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "autoClearAfterAddingToQueue",
}), func(checked bool) {
ItemsToConvert.isAutoRemove = checked
})
checkboxAutoRemove.SetChecked(ItemsToConvert.isAutoRemove)
localizerService.AddChangeCallback("autoClearAfterAddingToQueue", func(text string) {
checkboxAutoRemove.Text = text
})
buttonClear := widget.NewButton(localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "clearAll",
}), func() {
ItemsToConvert.clear()
})
buttonClear.Importance = widget.DangerImportance
localizerService.AddChangeCallback("clearAll", func(text string) {
buttonClear.Text = text
})
itemsContainer.Add(container.NewVBox(
container.NewPadded(),
container.NewBorder(nil, nil, nil, buttonClear, container.NewHScroll(checkboxAutoRemove)),
container.NewPadded(),
line,
container.NewPadded(),
containerForItems,
))
return ItemsToConvert
}
func (items *ItemsToConvert) Add(file *File) {
nextId := items.nextId
var content *fyne.Container
var buttonPlay *widget.Button
buttonPlay = widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
buttonPlay.Disable()
go func() {
_ = items.ffplayService.Run(FFplaySetting{
PathToFile: file.Path,
})
fyne.Do(func() {
buttonPlay.Enable()
})
}()
})
buttonRemove := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameDelete), func() {
items.itemsContainer.Remove(content)
items.itemsContainer.Refresh()
delete(items.items, nextId)
})
buttonRemove.Importance = widget.DangerImportance
content = container.NewVBox(
container.NewBorder(
nil,
nil,
buttonPlay,
buttonRemove,
container.NewHScroll(widget.NewLabel(file.Name)),
),
container.NewHScroll(widget.NewLabel(file.Path)),
container.NewPadded(),
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
container.NewPadded(),
)
items.itemsContainer.Add(content)
items.items[nextId] = NewItemToConvert(file, content)
items.nextId++
}
func (items *ItemsToConvert) GetItems() map[int]ItemToConvertContract {
return items.items
}
func (items *ItemsToConvert) AfterAddingQueue() {
if items.isAutoRemove {
items.clear()
}
}
func (items *ItemsToConvert) clear() {
items.itemsContainer.RemoveAll()
items.items = map[int]ItemToConvertContract{}
}
type ItemToConvertContract interface {
GetFile() *File
GetContent() *fyne.Container
}
type ItemToConvert struct {
file *File
content *fyne.Container
}
func NewItemToConvert(file *File, content *fyne.Container) *ItemToConvert {
return &ItemToConvert{
file: file,
content: content,
}
}
func (item ItemToConvert) GetFile() *File {
return item.file
}
func (item ItemToConvert) GetContent() *fyne.Container {
return item.content
}

View File

@ -1,6 +1,8 @@
package kernel package kernel
import ( import (
"bufio"
"errors"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
@ -8,31 +10,31 @@ import (
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
"io"
"regexp"
"strconv" "strconv"
"strings" "strings"
) )
type LayoutContract interface { type LayoutContract interface {
SetContent(content fyne.CanvasObject) *fyne.Container SetContent(content fyne.CanvasObject) *fyne.Container
NewProgressbar(queueId int, totalDuration float64) ProgressContract
ChangeQueueStatus(queueId int, queue *Queue) ChangeQueueStatus(queueId int, queue *Queue)
GetRightTabs() RightTabsContract
} }
type Layout struct { type Layout struct {
layout *fyne.Container layout *fyne.Container
queueLayoutObject QueueLayoutObjectContract queueLayoutObject QueueLayoutObjectContract
localizerService LocalizerContract localizerService LocalizerContract
rightTabsService RightTabsContract
} }
func NewLayout(queueLayoutObject QueueLayoutObjectContract, localizerService LocalizerContract, rightTabsService RightTabsContract) *Layout { func NewLayout(queueLayoutObject QueueLayoutObjectContract, localizerService LocalizerContract) *Layout {
layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), queueLayoutObject.GetCanvasObject()) layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), container.NewVScroll(queueLayoutObject.GetCanvasObject()))
return &Layout{ return &Layout{
layout: layout, layout: layout,
queueLayoutObject: queueLayoutObject, queueLayoutObject: queueLayoutObject,
localizerService: localizerService, localizerService: localizerService,
rightTabsService: rightTabsService,
} }
} }
@ -41,16 +43,18 @@ func (l Layout) SetContent(content fyne.CanvasObject) *fyne.Container {
return l.layout return l.layout
} }
func (l Layout) NewProgressbar(queueId int, totalDuration float64) ProgressContract {
progressbar := l.queueLayoutObject.GetProgressbar(queueId)
return NewProgress(totalDuration, progressbar, l.localizerService)
}
func (l Layout) ChangeQueueStatus(queueId int, queue *Queue) { func (l Layout) ChangeQueueStatus(queueId int, queue *Queue) {
l.queueLayoutObject.ChangeQueueStatus(queueId, queue) l.queueLayoutObject.ChangeQueueStatus(queueId, queue)
} }
func (l Layout) GetRightTabs() RightTabsContract {
return l.rightTabsService
}
type QueueLayoutObjectContract interface { type QueueLayoutObjectContract interface {
GetCanvasObject() fyne.CanvasObject GetCanvasObject() fyne.CanvasObject
GetProgressbar(queueId int) *widget.ProgressBar
ChangeQueueStatus(queueId int, queue *Queue) ChangeQueueStatus(queueId int, queue *Queue)
} }
@ -59,24 +63,21 @@ type QueueLayoutObject struct {
queue QueueListContract queue QueueListContract
container *fyne.Container container *fyne.Container
containerItems *fyne.Container
items map[int]QueueLayoutItem items map[int]QueueLayoutItem
localizerService LocalizerContract localizerService LocalizerContract
queueStatisticsFormat *queueStatisticsFormat queueStatisticsFormat *queueStatisticsFormat
ffplayService FFplayContract
} }
type QueueLayoutItem struct { type QueueLayoutItem struct {
CanvasObject fyne.CanvasObject CanvasObject fyne.CanvasObject
BlockMessageError *container.Scroll ProgressBar *widget.ProgressBar
StatusMessage *canvas.Text StatusMessage *canvas.Text
MessageError *canvas.Text MessageError *canvas.Text
buttonPlay *widget.Button
status *StatusContract status *StatusContract
} }
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract, rightTabsService RightTabsContract, blockProgressbar *fyne.Container) *QueueLayoutObject { func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract) *QueueLayoutObject {
title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"})) title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
title.TextStyle.Bold = true title.TextStyle.Bold = true
@ -88,31 +89,15 @@ func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerCon
items := map[int]QueueLayoutItem{} items := map[int]QueueLayoutItem{}
queueStatisticsFormat := newQueueStatisticsFormat(localizerService, &items) queueStatisticsFormat := newQueueStatisticsFormat(localizerService, &items)
line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
line.StrokeWidth = 5
rightTabsService.GetFileQueueContainer().Add(container.NewVBox(
container.NewPadded(),
container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget),
container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget),
container.NewPadded(),
line,
container.NewPadded(),
))
queueLayoutObject := &QueueLayoutObject{ queueLayoutObject := &QueueLayoutObject{
queue: queue, queue: queue,
container: container.NewBorder( container: container.NewVBox(
container.NewVBox( container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget),
blockProgressbar, container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget),
widget.NewSeparator(),
), ),
nil, nil, nil, container.NewVScroll(rightTabsService.GetTabs()),
),
containerItems: rightTabsService.GetFileQueueContainer(),
items: items, items: items,
localizerService: localizerService, localizerService: localizerService,
queueStatisticsFormat: queueStatisticsFormat, queueStatisticsFormat: queueStatisticsFormat,
ffplayService: ffplayService,
} }
queue.AddListener(queueLayoutObject) queue.AddListener(queueLayoutObject)
@ -124,24 +109,24 @@ func (o QueueLayoutObject) GetCanvasObject() fyne.CanvasObject {
return o.container return o.container
} }
func (o QueueLayoutObject) GetProgressbar(queueId int) *widget.ProgressBar {
if item, ok := o.items[queueId]; ok {
return item.ProgressBar
}
return widget.NewProgressBar()
}
func (o QueueLayoutObject) Add(id int, queue *Queue) { func (o QueueLayoutObject) Add(id int, queue *Queue) {
progressBar := widget.NewProgressBar()
statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary)) statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
messageError := canvas.NewText("", theme.Color(theme.ColorNameError)) messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
})
buttonPlay.Hide()
blockMessageError := container.NewHScroll(messageError)
blockMessageError.Hide()
content := container.NewVBox( content := container.NewVBox(
container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)), container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
container.NewHBox( progressBar,
buttonPlay, container.NewHScroll(statusMessage),
statusMessage, container.NewHScroll(messageError),
),
blockMessageError,
container.NewPadded(),
canvas.NewLine(theme.Color(theme.ColorNameFocus)), canvas.NewLine(theme.Color(theme.ColorNameFocus)),
container.NewPadded(), container.NewPadded(),
) )
@ -153,13 +138,12 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) {
o.items[id] = QueueLayoutItem{ o.items[id] = QueueLayoutItem{
CanvasObject: content, CanvasObject: content,
ProgressBar: progressBar,
StatusMessage: statusMessage, StatusMessage: statusMessage,
BlockMessageError: blockMessageError,
MessageError: messageError, MessageError: messageError,
buttonPlay: buttonPlay,
status: &queue.Status, status: &queue.Status,
} }
o.containerItems.Add(content) o.container.Add(content)
} }
func (o QueueLayoutObject) Remove(id int) { func (o QueueLayoutObject) Remove(id int) {
@ -182,24 +166,9 @@ func (o QueueLayoutObject) ChangeQueueStatus(queueId int, queue *Queue) {
item.MessageError.Text = queue.Error.Error() item.MessageError.Text = queue.Error.Error()
item.MessageError.Color = statusColor item.MessageError.Color = statusColor
fyne.Do(func() { fyne.Do(func() {
item.BlockMessageError.Show()
item.MessageError.Refresh() item.MessageError.Refresh()
}) })
} }
if queue.Status == StatusType(Completed) {
item.buttonPlay.Show()
item.buttonPlay.OnTapped = func() {
item.buttonPlay.Disable()
go func() {
_ = o.ffplayService.Run(FFplaySetting{
PathToFile: queue.Setting.VideoFileOut.Path,
})
fyne.Do(func() {
item.buttonPlay.Enable()
})
}()
}
}
if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true { if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
item.CanvasObject.Hide() item.CanvasObject.Hide()
} else if item.CanvasObject.Visible() == false { } else if item.CanvasObject.Visible() == false {
@ -225,6 +194,101 @@ func (o QueueLayoutObject) getStatusTitle(status StatusContract) string {
return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"}) return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"})
} }
type Progress struct {
totalDuration float64
progressbar *widget.ProgressBar
protocol string
localizerService LocalizerContract
}
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
return Progress{
totalDuration: totalDuration,
progressbar: progressbar,
protocol: "pipe:",
localizerService: localizerService,
}
}
func (p Progress) GetProtocole() string {
return p.protocol
}
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
isProcessCompleted := false
var errorText string
p.progressbar.Value = 0
p.progressbar.Max = p.totalDuration
fyne.Do(func() {
p.progressbar.Refresh()
})
progress := 0.0
go func() {
scannerErr := bufio.NewReader(stdErr)
for {
line, _, err := scannerErr.ReadLine()
if err != nil {
if err == io.EOF {
break
}
continue
}
data := strings.TrimSpace(string(line))
errorText = data
}
}()
scannerOut := bufio.NewReader(stdOut)
for {
line, _, err := scannerOut.ReadLine()
if err != nil {
if err == io.EOF {
break
}
continue
}
data := strings.TrimSpace(string(line))
if strings.Contains(data, "progress=end") {
p.progressbar.Value = p.totalDuration
fyne.Do(func() {
p.progressbar.Refresh()
})
isProcessCompleted = true
break
}
re := regexp.MustCompile(`frame=(\d+)`)
a := re.FindAllStringSubmatch(data, -1)
if len(a) > 0 && len(a[len(a)-1]) > 0 {
c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
if err != nil {
continue
}
progress = float64(c)
}
if p.progressbar.Value != progress {
p.progressbar.Value = progress
fyne.Do(func() {
p.progressbar.Refresh()
})
}
}
if isProcessCompleted == false {
if len(errorText) == 0 {
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "errorConverter",
})
}
return errors.New(errorText)
}
return nil
}
type queueStatistics struct { type queueStatistics struct {
widget *widget.Check widget *widget.Check
title string title string

View File

@ -1,254 +0,0 @@
package kernel
import (
"bufio"
"errors"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color"
"io"
"regexp"
"strconv"
"strings"
)
type BlockProgressbarContract interface {
GetContainer() *fyne.Container
GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress
ProcessEndedWithError(errorText string)
ProcessEndedWithSuccess(filePath string)
}
type BlockProgressbar struct {
container *fyne.Container
label *widget.Label
progressbar *widget.ProgressBar
errorBlock *container.Scroll
messageError *canvas.Text
statusMessage *canvas.Text
buttonPlay *widget.Button
statusesText *BlockProgressbarStatusesText
ffplayService FFplayContract
}
func NewBlockProgressbar(statusesText *BlockProgressbarStatusesText, ffplayService FFplayContract) *BlockProgressbar {
label := widget.NewLabel("")
progressbar := widget.NewProgressBar()
statusMessage := canvas.NewText("", theme.Color(theme.ColorNamePrimary))
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
})
buttonPlay.Hide()
errorBlock := container.NewHScroll(messageError)
errorBlock.Hide()
content := container.NewVBox(
container.NewHScroll(label),
progressbar,
container.NewHScroll(container.NewHBox(
buttonPlay,
statusMessage,
)),
errorBlock,
)
content.Hide()
return &BlockProgressbar{
container: content,
label: label,
progressbar: progressbar,
errorBlock: errorBlock,
messageError: messageError,
statusMessage: statusMessage,
buttonPlay: buttonPlay,
statusesText: statusesText,
ffplayService: ffplayService,
}
}
func (block BlockProgressbar) GetContainer() *fyne.Container {
return block.container
}
func (block BlockProgressbar) GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress {
block.label.Text = filePath
block.statusMessage.Color = theme.Color(theme.ColorNamePrimary)
block.statusMessage.Text = block.statusesText.inProgress
block.messageError.Text = ""
fyne.Do(func() {
block.buttonPlay.Hide()
if block.errorBlock.Visible() {
block.errorBlock.Hide()
}
block.statusMessage.Refresh()
block.container.Refresh()
block.errorBlock.Refresh()
})
block.progressbar.Value = 0
return NewProgress(totalDuration, block.progressbar, localizerService)
}
func (block BlockProgressbar) ProcessEndedWithError(errorText string) {
fyne.Do(func() {
block.statusMessage.Color = theme.Color(theme.ColorNameError)
block.statusMessage.Text = block.statusesText.error
block.messageError.Text = errorText
block.errorBlock.Show()
})
}
func (block BlockProgressbar) ProcessEndedWithSuccess(filePath string) {
fyne.Do(func() {
block.statusMessage.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
block.statusMessage.Text = block.statusesText.completed
block.buttonPlay.Show()
block.buttonPlay.OnTapped = func() {
block.buttonPlay.Disable()
go func() {
_ = block.ffplayService.Run(FFplaySetting{
PathToFile: filePath,
})
fyne.Do(func() {
block.buttonPlay.Enable()
})
}()
}
})
}
type Progress struct {
totalDuration float64
progressbar *widget.ProgressBar
protocol string
localizerService LocalizerContract
}
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
return Progress{
totalDuration: totalDuration,
progressbar: progressbar,
protocol: "pipe:",
localizerService: localizerService,
}
}
func (p Progress) GetProtocole() string {
return p.protocol
}
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
isProcessCompleted := false
var errorText string
p.progressbar.Value = 0
p.progressbar.Max = p.totalDuration
fyne.Do(func() {
p.progressbar.Refresh()
})
progress := 0.0
go func() {
scannerErr := bufio.NewReader(stdErr)
for {
line, _, err := scannerErr.ReadLine()
if err != nil {
if err == io.EOF {
break
}
continue
}
data := strings.TrimSpace(string(line))
errorText = data
}
}()
scannerOut := bufio.NewReader(stdOut)
for {
line, _, err := scannerOut.ReadLine()
if err != nil {
if err == io.EOF {
break
}
continue
}
data := strings.TrimSpace(string(line))
if strings.Contains(data, "progress=end") {
p.progressbar.Value = p.totalDuration
fyne.Do(func() {
p.progressbar.Refresh()
})
isProcessCompleted = true
break
}
re := regexp.MustCompile(`frame=(\d+)`)
a := re.FindAllStringSubmatch(data, -1)
if len(a) > 0 && len(a[len(a)-1]) > 0 {
c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
if err != nil {
continue
}
progress = float64(c)
}
if p.progressbar.Value != progress {
p.progressbar.Value = progress
fyne.Do(func() {
p.progressbar.Refresh()
})
}
}
if isProcessCompleted == false {
if len(errorText) == 0 {
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "errorConverter",
})
}
return errors.New(errorText)
}
return nil
}
type BlockProgressbarStatusesText struct {
inProgress string
completed string
error string
}
func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText {
statusesText := &BlockProgressbarStatusesText{
inProgress: localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "inProgressQueue",
}),
completed: localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "completedQueue",
}),
error: localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "errorQueue",
}),
}
localizerService.AddChangeCallback("inProgressQueue", func(text string) {
statusesText.inProgress = text
})
localizerService.AddChangeCallback("completedQueue", func(text string) {
statusesText.completed = text
})
localizerService.AddChangeCallback("errorQueue", func(text string) {
statusesText.error = text
})
return statusesText
}

View File

@ -1,76 +0,0 @@
package kernel
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"github.com/nicksnyder/go-i18n/v2/i18n"
)
type RightTabsContract interface {
GetTabs() *container.AppTabs
GetAddedFilesContainer() *fyne.Container
GetFileQueueContainer() *fyne.Container
SelectFileQueueTab()
SelectAddedFilesTab()
}
type RightTabs struct {
tabs *container.AppTabs
addedFilesContainer *fyne.Container
addedFilesTab *container.TabItem
fileQueueContainer *fyne.Container
fileQueueTab *container.TabItem
}
func NewRightTabs(localizerService LocalizerContract) *RightTabs {
addedFilesContainer := container.NewVBox()
addedFilesTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "addedFilesTitle"}), addedFilesContainer)
localizerService.AddChangeCallback("addedFilesTitle", func(text string) {
addedFilesTab.Text = text
})
fileQueueContainer := container.NewVBox()
fileQueueTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "fileQueueTitle"}), fileQueueContainer)
localizerService.AddChangeCallback("fileQueueTitle", func(text string) {
fileQueueTab.Text = text
})
tabs := container.NewAppTabs(
addedFilesTab,
fileQueueTab,
)
return &RightTabs{
tabs: tabs,
addedFilesContainer: addedFilesContainer,
addedFilesTab: addedFilesTab,
fileQueueContainer: fileQueueContainer,
fileQueueTab: fileQueueTab,
}
}
func (t RightTabs) GetTabs() *container.AppTabs {
return t.tabs
}
func (t RightTabs) GetAddedFilesContainer() *fyne.Container {
return t.addedFilesContainer
}
func (t RightTabs) GetFileQueueContainer() *fyne.Container {
return t.fileQueueContainer
}
func (t RightTabs) SelectFileQueueTab() {
fyne.Do(func() {
t.tabs.Select(t.fileQueueTab)
})
}
func (t RightTabs) SelectAddedFilesTab() {
fyne.Do(func() {
t.tabs.Select(t.addedFilesTab)
})
}

View File

@ -83,7 +83,5 @@ func (w Window) GetLayout() LayoutContract {
} }
func (w Window) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) { func (w Window) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) {
fyne.Do(func() {
w.windowFyne.SetOnDropped(callback) w.windowFyne.SetOnDropped(callback)
})
} }

View File

@ -10,14 +10,6 @@ other = "About"
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6" hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
other = "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself." other = "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself."
[addedFilesTitle]
hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
other = "Added files"
[autoClearAfterAddingToQueue]
hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
other = "Auto-clear after adding to queue"
[buttonDownloadFFmpeg] [buttonDownloadFFmpeg]
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b" hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
other = "Download FFmpeg automatically" other = "Download FFmpeg automatically"
@ -31,8 +23,8 @@ hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
other = "Cancel" other = "Cancel"
[changeFFPath] [changeFFPath]
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0" hash = "sha1-46793a2844600d0eb19fa3540fb9564ee5705491"
other = "FFmpeg, FFprobe and FFplay" other = "FFmpeg and FFprobe"
[changeLanguage] [changeLanguage]
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b" hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
@ -46,10 +38,6 @@ other = "Allow file to be overwritten"
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94" hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
other = "choose" other = "choose"
[clearAll]
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
other = "Clear List"
[completedQueue] [completedQueue]
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
other = "Completed" other = "Completed"
@ -74,9 +62,9 @@ other = "Will be downloaded from the site:"
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271" hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
other = "Downloading..." other = "Downloading..."
[dragAndDropFiles] [dragAndDrop1File]
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766" hash = "sha1-7259670822df1cc92ef5f06ed3c0e9407746975a"
other = "drag and drop files" other = "drag and drop 1 file"
[encoderGroupAudio] [encoderGroupAudio]
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba" hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
@ -234,13 +222,9 @@ other = "Couldn't convert video"
hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1" hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
other = "could not create file 'database' in folder 'data'" other = "could not create file 'database' in folder 'data'"
[errorDatabaseTimeout] [errorDragAndDrop1File]
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f" hash = "sha1-a8edb5cbd622f3ce4ec07a2377e22ec5fad4491b"
other = "Could not open configuration file.\nMake sure another copy of the program is not running!" other = "You can only drag and drop 1 file."
[errorDragAndDropFile]
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
other = "Not all files were added"
[errorFFmpeg] [errorFFmpeg]
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0" hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
@ -250,14 +234,6 @@ other = "this is not FFmpeg"
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f" hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
other = "Could not determine FFmpeg version" other = "Could not determine FFmpeg version"
[errorFFplay]
hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
other = "this is not FFplay"
[errorFFplayVersion]
hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
other = "Could not determine FFplay version"
[errorFFprobe] [errorFFprobe]
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8" hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
other = "this is not FFprobe" other = "this is not FFprobe"
@ -266,9 +242,9 @@ other = "this is not FFprobe"
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17" hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
other = "Failed to determine FFprobe version" other = "Failed to determine FFprobe version"
[errorNoFilesAddedForConversion] [errorIsFolder]
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314" hash = "sha1-f937d090b6e320957514d850657cdf2f911dc6aa"
other = "There are no files to convert" other = "You can only drag and drop a file"
[errorQueue] [errorQueue]
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
@ -302,10 +278,6 @@ other = "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08" hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
other = "File:" other = "File:"
[fileQueueTitle]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Queue"
[formPreset] [formPreset]
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68" hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
other = "Preset" other = "Preset"
@ -322,102 +294,6 @@ other = "I sincerely thank you for your invaluable\n\r and timely assistance:"
hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f" hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
other = "Help" other = "Help"
[helpFFplay]
hash = "sha1-ecc294b8b3d217ee1c2d63dc2f0253c3d1b3712c"
other = "FFplay Player Keys"
[helpFFplayActivateFrameStepMode]
hash = "sha1-f47ede90932d69465f6197cb2a7cc4d1e3ab150e"
other = "Activate frame-by-frame mode."
[helpFFplayCycleVideoFiltersOrShowModes]
hash = "sha1-83bb702c777e4768cdc326a668d541c23ab759b7"
other = "A cycle of video filters or display modes."
[helpFFplayDecreaseVolume]
hash = "sha1-de28db96a9c22be885ec5067a13f8f17fd3954bc"
other = "Decrease the volume."
[helpFFplayDescription]
hash = "sha1-f5441f6aee76222c4120066575e80c2d177ac3c0"
other = "Description"
[helpFFplayDoubleClickLeftMouseButton]
hash = "sha1-2657aa576055769952dfcde570fc9b4765d594ad"
other = "double click\nleft mouse button"
[helpFFplayIncreaseVolume]
hash = "sha1-8ba7bde2d9a80f4a7cd122cf4973975698d3bd34"
other = "Increase the volume."
[helpFFplayKeyDown]
hash = "sha1-c5aefd2f8c6908a69b08fe4a2d235b1ae0113470"
other = "down"
[helpFFplayKeyHoldS]
hash = "sha1-89c5dd8287c15b3f40db66e06b038c34a715f02f"
other = "hold S"
[helpFFplayKeyLeft]
hash = "sha1-feb671890703fb0300a436744d34018bbc7ba13a"
other = "left"
[helpFFplayKeyRight]
hash = "sha1-a4f025d4bf7f90ee5bec6c48b2710bc9c5bbb267"
other = "right"
[helpFFplayKeySpace]
hash = "sha1-a367ad00358ec44edc1d54a96df6f9114b0f8697"
other = "SPACE"
[helpFFplayKeyUp]
hash = "sha1-e4845aa8c0e100a80eaf65446c59085236fd2098"
other = "up"
[helpFFplayKeys]
hash = "sha1-0ad272ade8c568f394499f1492ecfab56e701e5d"
other = "Keys"
[helpFFplayPause]
hash = "sha1-e83e107900fde0c39295f599c2cf8fba8d8cb604"
other = "Pause or continue playing."
[helpFFplayQuit]
hash = "sha1-70785a2fd5d5a6519b7439f0d8cfcd7d54c5771d"
other = "Close the player."
[helpFFplaySeekBForward10Minutes]
hash = "sha1-58ed63343376240f2596e447b5245c1805f35234"
other = "Fast forward 10 minutes."
[helpFFplaySeekBForward1Minute]
hash = "sha1-3fe46b8d5413b7fdc53ae9ed9427bcb1769ec74c"
other = "Fast forward 1 minute."
[helpFFplaySeekBackward10Minutes]
hash = "sha1-927dffe9af72ffd40f46873b452a4c90627bccf8"
other = "Rewind 10 minutes."
[helpFFplaySeekBackward10Seconds]
hash = "sha1-e97615ecec0f8cf5647e8802bdda38dc2b0d809f"
other = "Rewind 10 seconds."
[helpFFplaySeekBackward1Minute]
hash = "sha1-5b19e280a0850122c8ebc80c622491bb09520e1a"
other = "Rewind 1 minute."
[helpFFplaySeekForward10Seconds]
hash = "sha1-8d840251d4a1668edaea3515df197a8a79031ec3"
other = "Fast forward 10 seconds."
[helpFFplayToggleFullScreen]
hash = "sha1-d32df02849258c5b02f15e5711f54ee6a8a75fd4"
other = "Switch to full screen or exit full screen."
[helpFFplayToggleMute]
hash = "sha1-4bdbb124fe8de3a8037c1e74719e9600b21b25ab"
other = "Mute or unmute."
[inProgressQueue] [inProgressQueue]
hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
other = "In Progress" other = "In Progress"
@ -438,14 +314,6 @@ other = "License information"
hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7" hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
other = "Licenses from other products used in the program" other = "Licenses from other products used in the program"
[menuSettingsLanguage]
hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
other = "Language"
[menuSettingsTheme]
hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
other = "Theme"
[or] [or]
hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b" hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
other = "or" other = "or"
@ -458,10 +326,6 @@ other = "Enable option"
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6" hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
other = "Path to FFmpeg:" other = "Path to FFmpeg:"
[pathToFfplay]
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
other = "Path to FFplay:"
[pathToFfprobe] [pathToFfprobe]
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024" hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
other = "Path to FFprobe:" other = "Path to FFprobe:"
@ -542,18 +406,6 @@ other = "Settings"
hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976" hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
other = "Checking FFmpeg for serviceability..." other = "Checking FFmpeg for serviceability..."
[themesNameDark]
hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
other = "Dark"
[themesNameDefault]
hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
other = "Default"
[themesNameLight]
hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
other = "Light"
[titleDownloadLink] [titleDownloadLink]
hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49" hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
other = "You can download it from here" other = "You can download it from here"

View File

@ -10,14 +10,6 @@ other = "Бағдарлама туралы"
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6" hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін." other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін."
[addedFilesTitle]
hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
other = "Қосылған файлдар"
[autoClearAfterAddingToQueue]
hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
other = "Кезекке қосқаннан кейін тазалаңыз"
[buttonDownloadFFmpeg] [buttonDownloadFFmpeg]
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b" hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
other = "FFmpeg автоматты түрде жүктеп алыңыз" other = "FFmpeg автоматты түрде жүктеп алыңыз"
@ -31,8 +23,8 @@ hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
other = "Болдырмау" other = "Болдырмау"
[changeFFPath] [changeFFPath]
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0" hash = "sha1-46793a2844600d0eb19fa3540fb9564ee5705491"
other = "FFmpeg, FFprobe және FFplay" other = "FFmpeg және FFprobe"
[changeLanguage] [changeLanguage]
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b" hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
@ -46,10 +38,6 @@ other = "Файлды қайта жазуға рұқсат беріңіз"
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94" hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
other = "таңдау" other = "таңдау"
[clearAll]
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
other = "Тізімді өшіру"
[completedQueue] [completedQueue]
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
other = "Дайын" other = "Дайын"
@ -74,9 +62,9 @@ other = "Сайттан жүктеледі:"
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271" hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
other = "Жүктеп алынуда..." other = "Жүктеп алынуда..."
[dragAndDropFiles] [dragAndDrop1File]
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766" hash = "sha1-7259670822df1cc92ef5f06ed3c0e9407746975a"
other = "файлдарды сүйреп апарыңыз" other = "1 файлды сүйреңіз"
[encoderGroupAudio] [encoderGroupAudio]
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba" hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
@ -234,13 +222,9 @@ other = "Бейнені түрлендіру мүмкін болмады"
hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1" hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
other = "'data' қалтасында 'database' файлын жасау мүмкін болмады" other = "'data' қалтасында 'database' файлын жасау мүмкін болмады"
[errorDatabaseTimeout] [errorDragAndDrop1File]
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f" hash = "sha1-a8edb5cbd622f3ce4ec07a2377e22ec5fad4491b"
other = "Конфигурация файлын аша алмады.\nБағдарламаның басқа көшірмесі іске қосылмағанына көз жеткізіңіз!" other = "Тек 1 файлды сүйреп апаруға болады"
[errorDragAndDropFile]
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
other = "Барлық файлдар қосылмаған"
[errorFFmpeg] [errorFFmpeg]
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0" hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
@ -250,14 +234,6 @@ other = "бұл FFmpeg емес"
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f" hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
other = "FFmpeg нұсқасын анықтау мүмкін болмады" other = "FFmpeg нұсқасын анықтау мүмкін болмады"
[errorFFplay]
hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
other = "бұл FFplay емес"
[errorFFplayVersion]
hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
other = "FFplay нұсқасын анықтау мүмкін болмады"
[errorFFprobe] [errorFFprobe]
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8" hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
other = "бұл FFprobe емес" other = "бұл FFprobe емес"
@ -266,9 +242,9 @@ other = "бұл FFprobe емес"
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17" hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
other = "FFprobe нұсқасын анықтау мүмкін болмады" other = "FFprobe нұсқасын анықтау мүмкін болмады"
[errorNoFilesAddedForConversion] [errorIsFolder]
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314" hash = "sha1-f937d090b6e320957514d850657cdf2f911dc6aa"
other = "Түрлендіруге арналған файлдар жоқ" other = "Тек файлды сүйреп апаруға болады"
[errorQueue] [errorQueue]
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
@ -302,10 +278,6 @@ other = "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08" hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
other = "Файл:" other = "Файл:"
[fileQueueTitle]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Кезек"
[formPreset] [formPreset]
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68" hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
other = "Алдын ала орнатылған" other = "Алдын ала орнатылған"
@ -322,102 +294,6 @@ other = "Сізге баға жетпес және уақтылы көмекте
hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f" hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
other = "Анықтама" other = "Анықтама"
[helpFFplay]
hash = "sha1-ecc294b8b3d217ee1c2d63dc2f0253c3d1b3712c"
other = "FFplay ойнатқышының пернелері"
[helpFFplayActivateFrameStepMode]
hash = "sha1-f47ede90932d69465f6197cb2a7cc4d1e3ab150e"
other = "Уақыт аралығын іске қосыңыз."
[helpFFplayCycleVideoFiltersOrShowModes]
hash = "sha1-83bb702c777e4768cdc326a668d541c23ab759b7"
other = "Бейне сүзгілерінің немесе дисплей режимдерінің циклі."
[helpFFplayDecreaseVolume]
hash = "sha1-de28db96a9c22be885ec5067a13f8f17fd3954bc"
other = "Дыбыс деңгейін төмендетіңіз."
[helpFFplayDescription]
hash = "sha1-f5441f6aee76222c4120066575e80c2d177ac3c0"
other = "Сипаттама"
[helpFFplayDoubleClickLeftMouseButton]
hash = "sha1-2657aa576055769952dfcde570fc9b4765d594ad"
other = "тінтуірдің сол жақ\nбатырмасын екі рет басу"
[helpFFplayIncreaseVolume]
hash = "sha1-8ba7bde2d9a80f4a7cd122cf4973975698d3bd34"
other = "Дыбыс деңгейін арттыру."
[helpFFplayKeyDown]
hash = "sha1-c5aefd2f8c6908a69b08fe4a2d235b1ae0113470"
other = "төмен"
[helpFFplayKeyHoldS]
hash = "sha1-89c5dd8287c15b3f40db66e06b038c34a715f02f"
other = "ұстау S"
[helpFFplayKeyLeft]
hash = "sha1-feb671890703fb0300a436744d34018bbc7ba13a"
other = "сол"
[helpFFplayKeyRight]
hash = "sha1-a4f025d4bf7f90ee5bec6c48b2710bc9c5bbb267"
other = "құқық"
[helpFFplayKeySpace]
hash = "sha1-a367ad00358ec44edc1d54a96df6f9114b0f8697"
other = "SPACE (пробел)"
[helpFFplayKeyUp]
hash = "sha1-e4845aa8c0e100a80eaf65446c59085236fd2098"
other = "жоғары"
[helpFFplayKeys]
hash = "sha1-0ad272ade8c568f394499f1492ecfab56e701e5d"
other = "Кілттер"
[helpFFplayPause]
hash = "sha1-e83e107900fde0c39295f599c2cf8fba8d8cb604"
other = "Кідіртіңіз немесе жоғалтуды жалғастырыңыз."
[helpFFplayQuit]
hash = "sha1-70785a2fd5d5a6519b7439f0d8cfcd7d54c5771d"
other = "Ойнатқышты жабыңыз."
[helpFFplaySeekBForward10Minutes]
hash = "sha1-58ed63343376240f2596e447b5245c1805f35234"
other = "10 минутқа алға айналдырыңыз."
[helpFFplaySeekBForward1Minute]
hash = "sha1-3fe46b8d5413b7fdc53ae9ed9427bcb1769ec74c"
other = "1 минутқа алға айналдырыңыз."
[helpFFplaySeekBackward10Minutes]
hash = "sha1-927dffe9af72ffd40f46873b452a4c90627bccf8"
other = "10 минутқа артқа айналдырыңыз."
[helpFFplaySeekBackward10Seconds]
hash = "sha1-e97615ecec0f8cf5647e8802bdda38dc2b0d809f"
other = "10 секундқа артқа айналдырыңыз."
[helpFFplaySeekBackward1Minute]
hash = "sha1-5b19e280a0850122c8ebc80c622491bb09520e1a"
other = "1 минутқа артқа айналдырыңыз."
[helpFFplaySeekForward10Seconds]
hash = "sha1-8d840251d4a1668edaea3515df197a8a79031ec3"
other = "10 секунд алға айналдырыңыз."
[helpFFplayToggleFullScreen]
hash = "sha1-d32df02849258c5b02f15e5711f54ee6a8a75fd4"
other = "Толық экранға ауысу немесе толық экраннан шығу."
[helpFFplayToggleMute]
hash = "sha1-4bdbb124fe8de3a8037c1e74719e9600b21b25ab"
other = "Дыбысты өшіріңіз немесе дыбысты қосыңыз."
[inProgressQueue] [inProgressQueue]
hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
other = "Орындалуда" other = "Орындалуда"
@ -438,14 +314,6 @@ other = "Лицензия туралы ақпарат"
hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7" hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
other = "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары" other = "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары"
[menuSettingsLanguage]
hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
other = "Тіл"
[menuSettingsTheme]
hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
other = "Тақырып"
[or] [or]
hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b" hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
other = "немесе" other = "немесе"
@ -458,10 +326,6 @@ other = "Опцияны қосу"
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6" hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
other = "FFmpeg жол:" other = "FFmpeg жол:"
[pathToFfplay]
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
other = "FFplay жол:"
[pathToFfprobe] [pathToFfprobe]
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024" hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
other = "FFprobe жол:" other = "FFprobe жол:"
@ -542,18 +406,6 @@ other = "Параметрлер"
hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976" hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
other = "FFmpeg функционалдығы тексерілуде..." other = "FFmpeg функционалдығы тексерілуде..."
[themesNameDark]
hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
other = "Қараңғы тақырып"
[themesNameDefault]
hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
other = "Әдепкі бойынша"
[themesNameLight]
hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
other = "Жеңіл тақырып"
[titleDownloadLink] [titleDownloadLink]
hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49" hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
other = "Сіз оны осы жерден жүктей аласыз" other = "Сіз оны осы жерден жүктей аласыз"

View File

@ -1,23 +1,20 @@
AlsoUsedProgram = "Также в программе используется:" AlsoUsedProgram = "Также в программе используется:"
about = "О программе" about = "О программе"
aboutText = "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg." aboutText = "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg."
addedFilesTitle = "Добавленные файлы"
autoClearAfterAddingToQueue = "Очищать после добавления в очередь"
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg" buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
buttonForSelectedDirTitle = "Сохранить в папку:" buttonForSelectedDirTitle = "Сохранить в папку:"
cancel = "Отмена" cancel = "Отмена"
changeFFPath = "FFmpeg, FFprobe и FFplay" changeFFPath = "FFmpeg и FFprobe"
changeLanguage = "Поменять язык" changeLanguage = "Поменять язык"
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл" checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
choose = "выбрать" choose = "выбрать"
clearAll = "Очистить список"
completedQueue = "Готово" completedQueue = "Готово"
converterVideoFilesSubmitTitle = "Конвертировать" converterVideoFilesSubmitTitle = "Конвертировать"
converterVideoFilesTitle = "Конвертер видео, аудио и картинок" converterVideoFilesTitle = "Конвертер видео, аудио и картинок"
download = "Скачать" download = "Скачать"
downloadFFmpegFromSite = "Будет скачано с сайта:" downloadFFmpegFromSite = "Будет скачано с сайта:"
downloadRun = "Скачивается..." downloadRun = "Скачивается..."
dragAndDropFiles = "перетащить файлы" dragAndDrop1File = "перетащить 1 файл"
encoderGroupAudio = "Аудио" encoderGroupAudio = "Аудио"
encoderGroupImage = "Картинки" encoderGroupImage = "Картинки"
encoderGroupVideo = "Видео" encoderGroupVideo = "Видео"
@ -57,15 +54,12 @@ encoder_xbm = "XBM (X BitMap) image"
error = "Произошла ошибка!" error = "Произошла ошибка!"
errorConverter = "не смогли отконвертировать видео" errorConverter = "не смогли отконвертировать видео"
errorDatabase = "не смогли создать файл 'database' в папке 'data'" errorDatabase = "не смогли создать файл 'database' в папке 'data'"
errorDatabaseTimeout = "Не смогли открыть файл конфигурации.\nУбедитесь, что другая копия программы не запущена!" errorDragAndDrop1File = "Можно перетащить только 1 файл"
errorDragAndDropFile = "Не все файлы добавились"
errorFFmpeg = "это не FFmpeg" errorFFmpeg = "это не FFmpeg"
errorFFmpegVersion = "Не смогли определить версию FFmpeg" errorFFmpegVersion = "Не смогли определить версию FFmpeg"
errorFFplay = "это не FFplay"
errorFFplayVersion = "Не смогли определить версию FFplay"
errorFFprobe = "это не FFprobe" errorFFprobe = "это не FFprobe"
errorFFprobeVersion = "Не смогли определить версию FFprobe" errorFFprobeVersion = "Не смогли определить версию FFprobe"
errorNoFilesAddedForConversion = "Нет файлов для конвертации" errorIsFolder = "Можно перетаскивать только файл"
errorQueue = "Ошибка" errorQueue = "Ошибка"
errorSelectedEncoder = "Конвертер не выбран" errorSelectedEncoder = "Конвертер не выбран"
errorSelectedFolderSave = "Папка для сохранения не выбрана!" errorSelectedFolderSave = "Папка для сохранения не выбрана!"
@ -74,46 +68,18 @@ exit = "Выход"
ffmpegLGPL = "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**." ffmpegLGPL = "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."
ffmpegTrademark = "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**." ffmpegTrademark = "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**."
fileForConversionTitle = "Файл:" fileForConversionTitle = "Файл:"
fileQueueTitle = "Очередь"
formPreset = "Предустановка" formPreset = "Предустановка"
gratitude = "Благодарность" gratitude = "Благодарность"
gratitudeText = "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:" gratitudeText = "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:"
help = "Справка" help = "Справка"
helpFFplay = "Клавиши проигрывателя FFplay"
helpFFplayActivateFrameStepMode = "Активировать покадровый режим."
helpFFplayCycleVideoFiltersOrShowModes = "Цикл видеофильтров или режимов показа."
helpFFplayDecreaseVolume = "Уменьшить громкость."
helpFFplayDescription = "Описание"
helpFFplayDoubleClickLeftMouseButton = "двойной щелчок\nлевой кнопкой мыши"
helpFFplayIncreaseVolume = "Увеличить громкость."
helpFFplayKeyDown = "вниз"
helpFFplayKeyHoldS = "держать S"
helpFFplayKeyLeft = "лево"
helpFFplayKeyRight = "право"
helpFFplayKeySpace = "SPACE (пробел)"
helpFFplayKeyUp = "вверх"
helpFFplayKeys = "Клавиши"
helpFFplayPause = "Поставить на паузу или продолжить проигрывать."
helpFFplayQuit = "Закрыть проигрыватель."
helpFFplaySeekBForward10Minutes = "Перемотать вперёд на 10 минут."
helpFFplaySeekBForward1Minute = "Перемотать вперёд на 1 минуту."
helpFFplaySeekBackward10Minutes = "Перемотать назад на 10 минут."
helpFFplaySeekBackward10Seconds = "Перемотать назад на 10 секунд."
helpFFplaySeekBackward1Minute = "Перемотать назад на 1 минуту."
helpFFplaySeekForward10Seconds = "Перемотать вперёд на 10 секунд."
helpFFplayToggleFullScreen = "Переключиться на полный экран или выйти с полного экрана."
helpFFplayToggleMute = "Отключить звук или включить звук."
inProgressQueue = "Выполняется" inProgressQueue = "Выполняется"
languageSelectionFormHead = "Переключить язык" languageSelectionFormHead = "Переключить язык"
languageSelectionHead = "Выберите язык" languageSelectionHead = "Выберите язык"
licenseLink = "Сведения о лицензии" licenseLink = "Сведения о лицензии"
licenseLinkOther = "Лицензии от других продуктов, которые используются в программе" licenseLinkOther = "Лицензии от других продуктов, которые используются в программе"
menuSettingsLanguage = "Язык"
menuSettingsTheme = "Тема"
or = "или" or = "или"
parameterCheckbox = "Включить параметр" parameterCheckbox = "Включить параметр"
pathToFfmpeg = "Путь к FFmpeg:" pathToFfmpeg = "Путь к FFmpeg:"
pathToFfplay = "Путь к FFplay:"
pathToFfprobe = "Путь к FFprobe:" pathToFfprobe = "Путь к FFprobe:"
preset_fast = "fast (медленней чем faster, но будет файл и меньше весить)" preset_fast = "fast (медленней чем faster, но будет файл и меньше весить)"
preset_faster = "faster (медленней чем veryfast, но будет файл и меньше весить)" preset_faster = "faster (медленней чем veryfast, но будет файл и меньше весить)"
@ -134,9 +100,6 @@ selectFFPathTitle = "Укажите путь к FFmpeg и к FFprobe"
selectFormat = "Расширение файла:" selectFormat = "Расширение файла:"
settings = "Настройки" settings = "Настройки"
testFF = "Проверка FFmpeg на работоспособность..." testFF = "Проверка FFmpeg на работоспособность..."
themesNameDark = "Тёмная"
themesNameDefault = "По умолчанию"
themesNameLight = "Светлая"
titleDownloadLink = "Скачать можно от сюда" titleDownloadLink = "Скачать можно от сюда"
total = "Всего" total = "Всего"
unzipRun = "Распаковывается..." unzipRun = "Распаковывается..."

30
main.go
View File

@ -12,7 +12,6 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/menu" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/menu"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/migration" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/migration"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
"golang.org/x/text/language" "golang.org/x/text/language"
"os" "os"
@ -27,26 +26,24 @@ func init() {
appMetadata := &fyne.AppMetadata{ appMetadata := &fyne.AppMetadata{
ID: "net.kor-elf.projects.gui-for-ffmpeg", ID: "net.kor-elf.projects.gui-for-ffmpeg",
Name: "GUI for FFmpeg", Name: "GUI for FFmpeg",
Version: "0.9.0", Version: "0.8.0",
Icon: iconResource, Icon: iconResource,
} }
localizerService, err := kernel.NewLocalizer("languages", language.Russian) localizerService, err := kernel.NewLocalizer("languages", language.Russian)
if err != nil { if err != nil {
kernel.PanicErrorLang(err, appMetadata) kernel.PanicErrorLang(err, appMetadata)
return
} }
ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""} ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: ""}
convertorService := kernel.NewService(ffPathUtilities) convertorService := kernel.NewService(ffPathUtilities)
ffplayService := kernel.NewFFplay(ffPathUtilities)
queue := kernel.NewQueueList() queue := kernel.NewQueueList()
application = kernel.NewApp( application = kernel.NewApp(
appMetadata, appMetadata,
localizerService, localizerService,
queue, queue,
ffplayService, kernel.NewQueueLayoutObject(queue, localizerService),
convertorService, convertorService,
) )
} }
@ -95,33 +92,16 @@ func main() {
} }
ffPathUtilities.FFprobe = pathFFprobe ffPathUtilities.FFprobe = pathFFprobe
pathFFplay, err := convertorRepository.GetPathFfplay()
if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
errorView.PanicError(err)
application.GetWindow().ShowAndRun()
return
}
ffPathUtilities.FFplay = pathFFplay
application.RunConvertor() application.RunConvertor()
defer application.AfterClosing() defer application.AfterClosing()
localizerView := localizer.NewView(application) localizerView := localizer.NewView(application)
convertorView := convertor.NewView(application) convertorView := convertor.NewView(application)
itemsToConvertService := kernel.NewItemsToConvert( convertorHandler := handler.NewConvertorHandler(application, convertorView, errorView, convertorRepository, settingDirectoryForSaving)
application.GetWindow().GetLayout().GetRightTabs().GetAddedFilesContainer(),
application.GetFFplayService(),
application.GetLocalizerService(),
)
convertorHandler := handler.NewConvertorHandler(application, convertorView, errorView, convertorRepository, settingDirectoryForSaving, itemsToConvertService)
themeRepository := theme.NewRepository(settingRepository)
themeService := theme.NewTheme(application, themeRepository)
localizerRepository := localizer.NewRepository(settingRepository) localizerRepository := localizer.NewRepository(settingRepository)
menuView := menu.NewView(application) menuView := menu.NewView(application)
menuSettingView := menu.NewViewSetting(application, themeService) mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, localizerView, localizerRepository)
mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, menuSettingView, localizerView, localizerRepository, themeService)
mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu, localizerRepository) mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu, localizerRepository)
mainHandler.Start() mainHandler.Start()

View File

@ -4,7 +4,6 @@ import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
@ -13,9 +12,8 @@ import (
) )
type ViewContract interface { type ViewContract interface {
About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) About(ffmpegVersion string, ffprobeVersion string)
Gratitude() Gratitude()
HelpFFplay()
} }
type View struct { type View struct {
@ -62,7 +60,7 @@ func (v View) Gratitude() {
view.Show() view.Show()
} }
func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) { func (v View) About(ffmpegVersion string, ffprobeVersion string) {
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "about", MessageID: "about",
})) }))
@ -136,7 +134,6 @@ func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion s
)), )),
v.getAboutFfmpeg(ffmpegVersion), v.getAboutFfmpeg(ffmpegVersion),
v.getAboutFfprobe(ffprobeVersion), v.getAboutFfprobe(ffprobeVersion),
v.getAboutFfplay(ffplayVersion),
widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{ widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "AlsoUsedProgram", MessageID: "AlsoUsedProgram",
}), "", v.getOther()), }), "", v.getOther()),
@ -146,151 +143,6 @@ func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion s
view.Show() view.Show()
} }
func (v View) HelpFFplay() {
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplay",
}))
view.Resize(fyne.Size{Width: 800, Height: 550})
view.SetFixedSize(true)
data := [][]string{
[]string{
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeys",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayDescription",
}),
},
[]string{
"Q, ESC",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayQuit",
}),
},
[]string{
"F, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayDoubleClickLeftMouseButton",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayToggleFullScreen",
}),
},
[]string{
"P, " +
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeySpace",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayPause",
}),
},
[]string{
"M",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayToggleMute",
}),
},
[]string{
"9, /",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayDecreaseVolume",
}),
},
[]string{
"0, *",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayIncreaseVolume",
}),
},
[]string{
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeyLeft",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward10Seconds",
}),
},
[]string{
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeyRight",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekForward10Seconds",
}),
},
[]string{
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeyDown",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward1Minute",
}),
},
[]string{
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeyUp",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBForward1Minute",
}),
},
[]string{
"Page Down",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward10Minutes",
}),
},
[]string{
"Page Up",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBForward10Minutes",
}),
},
[]string{
"S, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayKeyHoldS",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayActivateFrameStepMode",
}),
},
[]string{
"W",
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayCycleVideoFiltersOrShowModes",
}),
},
}
list := widget.NewTable(
func() (int, int) {
return len(data), len(data[0])
},
func() fyne.CanvasObject {
return widget.NewLabel("")
},
func(i widget.TableCellID, o fyne.CanvasObject) {
if i.Row == 0 {
o.(*widget.Label).TextStyle.Bold = true
o.(*widget.Label).SizeName = theme.SizeNameSubHeadingText
}
if i.Col == 0 {
o.(*widget.Label).TextStyle.Bold = true
}
o.(*widget.Label).SetText(data[i.Row][i.Col])
})
list.SetRowHeight(0, 40)
list.SetColumnWidth(0, 200)
list.SetColumnWidth(1, 585)
list.SetRowHeight(2, 55)
view.SetContent(
container.NewScroll(list),
)
view.CenterOnScreen()
view.Show()
}
func (v View) getCopyright() *widget.RichText { func (v View) getCopyright() *widget.RichText {
return widget.NewRichTextFromMarkdown("Copyright (c) 2024 **[Leonid Nikitin (kor-elf)](https://git.kor-elf.net/kor-elf/)**.") return widget.NewRichTextFromMarkdown("Copyright (c) 2024 **[Leonid Nikitin (kor-elf)](https://git.kor-elf.net/kor-elf/)**.")
} }
@ -355,36 +207,6 @@ func (v View) getAboutFfprobe(version string) *fyne.Container {
) )
} }
func (v View) getAboutFfplay(version string) *fyne.Container {
programmName := canvas.NewText(" FFplay", colornames.Darkgreen)
programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20
programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "programmLink",
}), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "ffplay.html",
})
licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "licenseLink",
}), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "legal.html",
})
return container.NewVBox(
programmName,
widget.NewLabel(version),
widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
container.NewHBox(programmLink, licenseLink),
)
}
func (v View) getOther() *fyne.Container { func (v View) getOther() *fyne.Container {
return container.NewVBox( return container.NewVBox(
canvas.NewLine(colornames.Darkgreen), canvas.NewLine(colornames.Darkgreen),

View File

@ -1,112 +0,0 @@
package menu
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color"
)
type ViewSettingContract interface {
Main(
save func(*SettingForm) error,
cancel func(),
)
}
type SettingForm struct {
Language kernel.Lang
ThemeInfo theme.ThemeInfoContract
}
type ViewSetting struct {
app kernel.AppContract
themeService theme.ThemeContract
}
func NewViewSetting(app kernel.AppContract, themeService theme.ThemeContract) *ViewSetting {
return &ViewSetting{
app: app,
themeService: themeService,
}
}
func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
errorMessage.TextSize = 16
errorMessage.TextStyle = fyne.TextStyle{Bold: true}
viewSettingForm := &SettingForm{
Language: v.app.GetLocalizerService().GetCurrentLanguage().Lang,
ThemeInfo: v.themeService.GetCurrentThemeInfo(),
}
languageItems := []string{}
langByTitle := map[string]kernel.Lang{}
for _, language := range v.app.GetLocalizerService().GetLanguages() {
languageItems = append(languageItems, language.Title)
langByTitle[language.Title] = language
}
selectLanguage := widget.NewSelect(languageItems, func(s string) {
if lang, ok := langByTitle[s]; ok {
viewSettingForm.Language = lang
}
})
selectLanguage.Selected = v.app.GetLocalizerService().GetCurrentLanguage().Lang.Title
themeItems := []string{}
themeByTitle := map[string]theme.ThemeInfoContract{}
for _, themeInfo := range v.themeService.List() {
themeItems = append(themeItems, themeInfo.GetTitle())
themeByTitle[themeInfo.GetTitle()] = themeInfo
}
selectTheme := widget.NewSelect(themeItems, func(s string) {
if themeInfo, ok := themeByTitle[s]; ok {
viewSettingForm.ThemeInfo = themeInfo
}
})
selectTheme.Selected = v.themeService.GetCurrentThemeInfo().GetTitle()
form := &widget.Form{
Items: []*widget.FormItem{
{
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "menuSettingsLanguage",
}),
Widget: selectLanguage,
},
{
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "menuSettingsTheme",
}),
Widget: selectTheme,
},
{
Widget: errorMessage,
},
},
SubmitText: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "save",
}),
OnSubmit: func() {
err := save(viewSettingForm)
if err != nil {
errorMessage.Text = err.Error()
}
},
}
if cancel != nil {
form.OnCancel = cancel
form.CancelText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "cancel",
})
}
messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings",
})
v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", form))
}

View File

@ -1,28 +0,0 @@
package theme
import "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
type RepositoryContract interface {
GetCode() string
Save(code string) (setting.Setting, error)
}
type Repository struct {
settingRepository setting.RepositoryContract
}
func NewRepository(settingRepository setting.RepositoryContract) *Repository {
return &Repository{settingRepository: settingRepository}
}
func (r Repository) GetCode() string {
name, err := r.settingRepository.GetValue("theme")
if err != nil {
return "default"
}
return name
}
func (r Repository) Save(code string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("theme", code)
}

View File

@ -1,158 +0,0 @@
package theme
import (
"fyne.io/fyne/v2"
fyneTheme "fyne.io/fyne/v2/theme"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color"
)
type ThemeContract interface {
List() map[string]ThemeInfoContract
GetCurrentThemeInfo() ThemeInfoContract
SetCurrentTheme(themeInfo ThemeInfoContract) error
}
type theme struct {
app kernel.AppContract
repository RepositoryContract
list map[string]ThemeInfoContract
}
func NewTheme(app kernel.AppContract, repository RepositoryContract) ThemeContract {
theme := &theme{
app: app,
repository: repository,
list: getThemes(app.GetLocalizerService()),
}
theme.init()
return theme
}
func (t theme) init() {
themeInfo := t.GetCurrentThemeInfo()
if themeInfo.GetName() == "default" {
t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme())
return
}
t.app.GetAppFyne().Settings().SetTheme(&forcedVariant{theme: fyneTheme.DefaultTheme(), variant: themeInfo.GetVariant()})
}
func (t theme) GetCurrentThemeInfo() ThemeInfoContract {
themes := t.List()
if themeInfo, ok := themes[t.repository.GetCode()]; ok {
return themeInfo
}
return themes["default"]
}
func (t theme) List() map[string]ThemeInfoContract {
return t.list
}
func (t theme) SetCurrentTheme(themeInfo ThemeInfoContract) error {
_, err := t.repository.Save(themeInfo.GetName())
if err != nil {
return err
}
if themeInfo.GetName() == "default" {
t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme())
return nil
}
t.app.GetAppFyne().Settings().SetTheme(&forcedVariant{theme: fyneTheme.DefaultTheme(), variant: themeInfo.GetVariant()})
return nil
}
type ThemeInfoContract interface {
GetName() string
GetTitle() string
GetVariant() fyne.ThemeVariant
}
type themeInfo struct {
name string
title string
variant fyne.ThemeVariant
}
func (inf themeInfo) GetName() string {
return inf.name
}
func (inf themeInfo) GetTitle() string {
return inf.title
}
func (inf themeInfo) GetVariant() fyne.ThemeVariant {
return inf.variant
}
func getThemes(localizer kernel.LocalizerContract) map[string]ThemeInfoContract {
themesNameDefault := &themeInfo{
name: "default",
title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameDefault",
}),
}
themesNameLight := &themeInfo{
name: "light",
title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameLight",
}),
variant: fyneTheme.VariantLight,
}
themesNameDark := &themeInfo{
name: "dark",
title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameDark",
}),
variant: fyneTheme.VariantDark,
}
list := map[string]ThemeInfoContract{
"default": themesNameDefault,
"light": themesNameLight,
"dark": themesNameDark,
}
localizer.AddChangeCallback("themesNameDefault", func(text string) {
themesNameDefault.title = text
})
localizer.AddChangeCallback("themesNameLight", func(text string) {
themesNameLight.title = text
})
localizer.AddChangeCallback("themesNameDark", func(text string) {
themesNameDark.title = text
})
return list
}
type forcedVariant struct {
theme fyne.Theme
variant fyne.ThemeVariant
}
func (f *forcedVariant) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
return f.theme.Color(name, f.variant)
}
func (f *forcedVariant) Font(style fyne.TextStyle) fyne.Resource {
return fyneTheme.DefaultTheme().Font(style)
}
func (f *forcedVariant) Icon(name fyne.ThemeIconName) fyne.Resource {
return fyneTheme.DefaultTheme().Icon(name)
}
func (f *forcedVariant) Size(name fyne.ThemeSizeName) float32 {
return fyneTheme.DefaultTheme().Size(name)
}