5 Commits

52 changed files with 2122 additions and 992 deletions

View File

@@ -3,4 +3,7 @@
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.9.0"
Build = 11 Build = 4
[Migrations]
fyneDo = true

View File

@@ -25,7 +25,21 @@
* fyne-cross linux --icon icon.png --app-id "." -name "gui-for-ffmpeg" * fyne-cross linux --icon icon.png --app-id "." -name "gui-for-ffmpeg"
7. Создаться папка **fyne-cross/bin** и там будет созданна папка с тем названием под которую Вы компилировали приложения (linux-amd64 или windows-amd64). 7. Создаться папка **fyne-cross/bin** и там будет созданна папка с тем названием под которую Вы компилировали приложения (linux-amd64 или windows-amd64).
8. В папку **fyne-cross/bin/linux-amd64** или **fyne-cross/bin/windows-amd64** копируете: 8. В папку **fyne-cross/bin/linux-amd64** или **fyne-cross/bin/windows-amd64** копируете:
* icon.png
* data
* languages
* LICENSE * LICENSE
* LICENSE-3RD-PARTY.txt * LICENSE-3RD-PARTY.txt
<p><strong>Структура должна получиться такая:</strong></p> <p><strong>Структура должна получиться такая:</strong></p>
<img src="images/screenshot-folder-structure.png"> <img src="images/screenshot-folder-structure.png">
## Работа с переводами:
1. go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest
3. Создаём файл languages/translate.\*.toml
4. goi18n merge -sourceLanguage ru -outdir languages languages/active.\*.toml languages/translate.\*.toml
5. В файлах **languages/translate.\*.toml** переводим текст на нужный язык
6. goi18n merge -sourceLanguage ru -outdir languages languages/active.\*.toml languages/translate.\*.toml
___где * подставляем нужный язык___
Более подробно можно почитать тут: https://github.com/nicksnyder/go-i18n

View File

@@ -5,12 +5,12 @@ import (
) )
type RepositoryContract interface { type RepositoryContract interface {
GetPathFfmpeg() string GetPathFfmpeg() (string, error)
SavePathFfmpeg(code string) setting.Setting SavePathFfmpeg(code string) (setting.Setting, error)
GetPathFfprobe() string GetPathFfprobe() (string, error)
SavePathFfprobe(code string) setting.Setting SavePathFfprobe(code string) (setting.Setting, error)
GetPathFfplay() string GetPathFfplay() (string, error)
SavePathFfplay(code string) setting.Setting SavePathFfplay(code string) (setting.Setting, error)
} }
type Repository struct { type Repository struct {
@@ -21,26 +21,26 @@ func NewRepository(settingRepository setting.RepositoryContract) *Repository {
return &Repository{settingRepository: settingRepository} return &Repository{settingRepository: settingRepository}
} }
func (r Repository) GetPathFfmpeg() string { func (r Repository) GetPathFfmpeg() (string, error) {
return r.settingRepository.GetValue("ffmpeg") return r.settingRepository.GetValue("ffmpeg")
} }
func (r Repository) SavePathFfmpeg(path string) setting.Setting { func (r Repository) SavePathFfmpeg(path string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("ffmpeg", path) return r.settingRepository.CreateOrUpdate("ffmpeg", path)
} }
func (r Repository) GetPathFfprobe() string { func (r Repository) GetPathFfprobe() (string, error) {
return r.settingRepository.GetValue("ffprobe") return r.settingRepository.GetValue("ffprobe")
} }
func (r Repository) SavePathFfprobe(path string) setting.Setting { 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 { func (r Repository) GetPathFfplay() (string, error) {
return r.settingRepository.GetValue("ffplay") return r.settingRepository.GetValue("ffplay")
} }
func (r Repository) SavePathFfplay(path string) setting.Setting { func (r Repository) SavePathFfplay(path string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("ffplay", path) return r.settingRepository.CreateOrUpdate("ffplay", path)
} }

View File

@@ -7,6 +7,7 @@ import (
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view"
"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"
"image/color" "image/color"
) )
@@ -44,7 +45,9 @@ func NewView(app kernel.AppContract) *View {
} }
func (v View) Main(formConversion view.ConversionContract) { func (v View) Main(formConversion view.ConversionContract) {
converterVideoFilesTitle := v.app.GetLocalizerService().GetMessage("converterVideoFilesTitle") converterVideoFilesTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "converterVideoFilesTitle",
})
v.app.GetWindow().SetContent(widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(formConversion.GetContent()))) v.app.GetWindow().SetContent(widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(formConversion.GetContent())))
formConversion.AfterViewContent() formConversion.AfterViewContent()
} }

View File

@@ -12,6 +12,7 @@ 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/kernel/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
"os" "os"
"path/filepath" "path/filepath"
@@ -53,14 +54,14 @@ func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContr
items := []*widget.FormItem{ items := []*widget.FormItem{
{ {
Text: app.GetLocalizerService().GetMessage("fileForConversionTitle"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "fileForConversionTitle"}),
Widget: fileForConversion.button, Widget: fileForConversion.button,
}, },
{ {
Widget: container.NewHScroll(fileForConversion.message), Widget: container.NewHScroll(fileForConversion.message),
}, },
{ {
Text: app.GetLocalizerService().GetMessage("buttonForSelectedDirTitle"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "buttonForSelectedDirTitle"}),
Widget: directoryForSaving.button, Widget: directoryForSaving.button,
}, },
{ {
@@ -73,11 +74,11 @@ func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContr
Widget: selectEncoder.SelectFileType, Widget: selectEncoder.SelectFileType,
}, },
{ {
Text: app.GetLocalizerService().GetMessage("selectFormat"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectFormat"}),
Widget: selectEncoder.SelectFormat, Widget: selectEncoder.SelectFormat,
}, },
{ {
Text: app.GetLocalizerService().GetMessage("selectEncoder"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectEncoder"}),
Widget: selectEncoder.SelectEncoder, Widget: selectEncoder.SelectEncoder,
}, },
} }
@@ -140,22 +141,30 @@ func (c Conversion) selectFileForConversion(err error) {
func (c Conversion) submit() { func (c Conversion) submit() {
if len(c.itemsToConvertService.GetItems()) == 0 { if len(c.itemsToConvertService.GetItems()) == 0 {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage("errorNoFilesAddedForConversion"))) showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorNoFilesAddedForConversion",
})))
c.enableFormConversion() c.enableFormConversion()
return return
} }
if len(c.directoryForSaving.path) == 0 { if len(c.directoryForSaving.path) == 0 {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage("errorSelectedFolderSave"))) showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorSelectedFolderSave",
})))
c.enableFormConversion() c.enableFormConversion()
return return
} }
if len(c.selectEncoder.SelectFormat.Selected) == 0 { if len(c.selectEncoder.SelectFormat.Selected) == 0 {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage("errorSelectedFormat"))) showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorSelectedFormat",
})))
return return
} }
if c.selectEncoder.Encoder == nil { if c.selectEncoder.Encoder == nil {
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage("errorSelectedEncoder"))) showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorSelectedEncoder",
})))
return return
} }
c.conversionMessage.Text = "" c.conversionMessage.Text = ""
@@ -199,9 +208,13 @@ func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.I
changeCallbacks: map[int]func(err error){}, changeCallbacks: map[int]func(err error){},
} }
buttonTitle := app.GetLocalizerService().GetMessage("choose") + "\n" + buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
app.GetLocalizerService().GetMessage("or") + "\n" + MessageID: "choose",
app.GetLocalizerService().GetMessage("dragAndDropFiles") }) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "or",
}) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "dragAndDropFiles",
})
var locationURI fyne.ListableURI var locationURI fyne.ListableURI
@@ -268,7 +281,9 @@ func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.I
} }
app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab() app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
if isError { if isError {
fileForConversion.message.Text = app.GetLocalizerService().GetMessage("errorDragAndDropFile") fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorDragAndDropFile",
})
setStringErrorStyle(fileForConversion.message) setStringErrorStyle(fileForConversion.message)
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text)) fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
} else { } else {
@@ -307,7 +322,9 @@ func newDirectoryForSaving(app kernel.AppContract, settingDirectoryForSaving set
directoryForSaving.message.TextSize = 16 directoryForSaving.message.TextSize = 16
directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true} directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true}
buttonTitle := app.GetLocalizerService().GetMessage("choose") buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "choose",
})
var locationURI fyne.ListableURI var locationURI fyne.ListableURI
@@ -336,7 +353,7 @@ func newDirectoryForSaving(app kernel.AppContract, settingDirectoryForSaving set
locationURI, err = storage.ListerForURI(r) locationURI, err = storage.ListerForURI(r)
if err == nil { if err == nil {
_ = settingDirectoryForSaving.SaveDirectoryForSaving(locationURI.Path()) _, _ = settingDirectoryForSaving.SaveDirectoryForSaving(locationURI.Path())
} }
}, locationURI) }, locationURI)
@@ -346,7 +363,10 @@ func newDirectoryForSaving(app kernel.AppContract, settingDirectoryForSaving set
} }
func getDirectoryForSaving(settingDirectoryForSaving setting.DirectoryForSavingContract) (fyne.ListableURI, error) { func getDirectoryForSaving(settingDirectoryForSaving setting.DirectoryForSavingContract) (fyne.ListableURI, error) {
path := settingDirectoryForSaving.GetDirectoryForSaving() path, err := settingDirectoryForSaving.GetDirectoryForSaving()
if err != nil {
return nil, err
}
if len(path) > 0 { if len(path) > 0 {
path = "file://" + path path = "file://" + path
@@ -369,7 +389,9 @@ func newOverwriteOutputFiles(app kernel.AppContract) *overwriteOutputFiles {
overwriteOutputFiles := &overwriteOutputFiles{ overwriteOutputFiles := &overwriteOutputFiles{
isChecked: false, isChecked: false,
} }
checkboxOverwriteOutputFilesTitle := app.GetLocalizerService().GetMessage("checkboxOverwriteOutputFilesTitle") checkboxOverwriteOutputFilesTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "checkboxOverwriteOutputFilesTitle",
})
overwriteOutputFiles.checkbox = widget.NewCheck(checkboxOverwriteOutputFilesTitle, func(b bool) { overwriteOutputFiles.checkbox = widget.NewCheck(checkboxOverwriteOutputFilesTitle, func(b bool) {
overwriteOutputFiles.isChecked = b overwriteOutputFiles.isChecked = b
}) })
@@ -418,7 +440,7 @@ func newSelectEncoder(app kernel.AppContract, formats encoder.ConvertorFormatsCo
encoders = map[int]encoder2.EncoderDataContract{} encoders = map[int]encoder2.EncoderDataContract{}
for _, e := range format.GetEncoders() { for _, e := range format.GetEncoders() {
encoders[len(encoders)] = e encoders[len(encoders)] = e
encoderOptions = append(encoderOptions, app.GetLocalizerService().GetMessage("encoder_"+e.GetTitle())) encoderOptions = append(encoderOptions, app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoder_" + e.GetTitle()}))
} }
selectEncoder.SelectEncoder.SetOptions(encoderOptions) selectEncoder.SelectEncoder.SetOptions(encoderOptions)
selectEncoder.SelectEncoder.SetSelectedIndex(0) selectEncoder.SelectEncoder.SetSelectedIndex(0)
@@ -429,9 +451,9 @@ func newSelectEncoder(app kernel.AppContract, formats encoder.ConvertorFormatsCo
fileTypeOptions = append(fileTypeOptions, fileType.Name()) fileTypeOptions = append(fileTypeOptions, fileType.Name())
} }
encoderGroupVideo := app.GetLocalizerService().GetMessage("encoderGroupVideo") encoderGroupVideo := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupVideo"})
encoderGroupAudio := app.GetLocalizerService().GetMessage("encoderGroupAudio") encoderGroupAudio := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupAudio"})
encoderGroupImage := app.GetLocalizerService().GetMessage("encoderGroupImage") encoderGroupImage := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupImage"})
encoderGroup := map[string]string{ encoderGroup := map[string]string{
encoderGroupVideo: "video", encoderGroupVideo: "video",
encoderGroupAudio: "audio", encoderGroupAudio: "audio",
@@ -498,7 +520,9 @@ type form struct {
func newForm(app kernel.AppContract, items []*widget.FormItem) *form { func newForm(app kernel.AppContract, items []*widget.FormItem) *form {
f := widget.NewForm() f := widget.NewForm()
f.SubmitText = app.GetLocalizerService().GetMessage("converterVideoFilesSubmitTitle") f.SubmitText = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "converterVideoFilesSubmitTitle",
})
f.Items = items f.Items = items
return &form{ return &form{

View File

@@ -6,6 +6,7 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/h264_nvenc" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/h264_nvenc"
"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"
) )
func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem { func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
@@ -44,7 +45,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault) elementSelect.SetSelected(presetDefault)
elementSelect.Hide() elementSelect.Hide()
checkboxTitle := app.GetLocalizerService().GetMessage("parameterCheckbox") checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) { elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true { if b == true {
parameter.SetEnable() parameter.SetEnable()
@@ -57,7 +58,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{ return []*widget.FormItem{
{ {
Text: app.GetLocalizerService().GetMessage("formPreset"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
Widget: container.NewVBox(elementCheckbox, elementSelect), Widget: container.NewVBox(elementCheckbox, elementSelect),
}, },
} }

View File

@@ -6,6 +6,7 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx264" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx264"
"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"
) )
func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem { func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
@@ -27,7 +28,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
presetDefault := "" presetDefault := ""
for _, name := range libx264.Presets { for _, name := range libx264.Presets {
title := app.GetLocalizerService().GetMessage("preset_" + name) title := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "preset_" + name})
presetsForSelect = append(presetsForSelect, title) presetsForSelect = append(presetsForSelect, title)
presets[title] = name presets[title] = name
if name == parameter.Get() { if name == parameter.Get() {
@@ -44,7 +45,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault) elementSelect.SetSelected(presetDefault)
elementSelect.Hide() elementSelect.Hide()
checkboxTitle := app.GetLocalizerService().GetMessage("parameterCheckbox") checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) { elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true { if b == true {
parameter.SetEnable() parameter.SetEnable()
@@ -57,7 +58,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{ return []*widget.FormItem{
{ {
Text: app.GetLocalizerService().GetMessage("formPreset"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
Widget: container.NewVBox(elementCheckbox, elementSelect), Widget: container.NewVBox(elementCheckbox, elementSelect),
}, },
} }

View File

@@ -6,6 +6,7 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx265" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx265"
"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"
) )
func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem { func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
@@ -27,7 +28,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
presetDefault := "" presetDefault := ""
for _, name := range libx265.Presets { for _, name := range libx265.Presets {
title := app.GetLocalizerService().GetMessage("preset_" + name) title := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "preset_" + name})
presetsForSelect = append(presetsForSelect, title) presetsForSelect = append(presetsForSelect, title)
presets[title] = name presets[title] = name
if name == parameter.Get() { if name == parameter.Get() {
@@ -44,7 +45,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault) elementSelect.SetSelected(presetDefault)
elementSelect.Hide() elementSelect.Hide()
checkboxTitle := app.GetLocalizerService().GetMessage("parameterCheckbox") checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) { elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true { if b == true {
parameter.SetEnable() parameter.SetEnable()
@@ -57,7 +58,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{ return []*widget.FormItem{
{ {
Text: app.GetLocalizerService().GetMessage("formPreset"), Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
Widget: container.NewVBox(elementCheckbox, elementSelect), Widget: container.NewVBox(elementCheckbox, elementSelect),
}, },
} }

View File

@@ -6,6 +6,7 @@ import (
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
"net/url" "net/url"
"path/filepath" "path/filepath"
@@ -36,25 +37,33 @@ func (v View) SelectFFPath(
form := &widget.Form{ form := &widget.Form{
Items: []*widget.FormItem{ Items: []*widget.FormItem{
{ {
Text: v.app.GetLocalizerService().GetMessage("titleDownloadLink"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "titleDownloadLink",
}),
Widget: link, Widget: link,
}, },
{ {
Text: v.app.GetLocalizerService().GetMessage("pathToFfmpeg"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "pathToFfmpeg",
}),
Widget: buttonFFmpeg, Widget: buttonFFmpeg,
}, },
{ {
Widget: container.NewHScroll(buttonFFmpegMessage), Widget: container.NewHScroll(buttonFFmpegMessage),
}, },
{ {
Text: v.app.GetLocalizerService().GetMessage("pathToFfprobe"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "pathToFfprobe",
}),
Widget: buttonFFprobe, Widget: buttonFFprobe,
}, },
{ {
Widget: container.NewHScroll(buttonFFprobeMessage), Widget: container.NewHScroll(buttonFFprobeMessage),
}, },
{ {
Text: v.app.GetLocalizerService().GetMessage("pathToFfplay"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "pathToFfplay",
}),
Widget: buttonFFplay, Widget: buttonFFplay,
}, },
{ {
@@ -64,7 +73,9 @@ func (v View) SelectFFPath(
Widget: errorMessage, Widget: errorMessage,
}, },
}, },
SubmitText: v.app.GetLocalizerService().GetMessage("save"), SubmitText: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "save",
}),
OnSubmit: func() { OnSubmit: func() {
err := save(*ffmpegPath, *ffprobePath, *ffplayPath) err := save(*ffmpegPath, *ffprobePath, *ffplayPath)
if err != nil { if err != nil {
@@ -74,9 +85,13 @@ func (v View) SelectFFPath(
} }
if cancel != nil { if cancel != nil {
form.OnCancel = cancel form.OnCancel = cancel
form.CancelText = v.app.GetLocalizerService().GetMessage("cancel") form.CancelText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "cancel",
})
} }
selectFFPathTitle := v.app.GetLocalizerService().GetMessage("selectFFPathTitle") selectFFPathTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "selectFFPathTitle",
})
if v.downloadFFmpeg.blockDownloadFFmpegContainer == nil { if v.downloadFFmpeg.blockDownloadFFmpegContainer == nil {
v.downloadFFmpeg.blockDownloadFFmpegContainer = v.blockDownloadFFmpeg(donwloadFFmpeg) v.downloadFFmpeg.blockDownloadFFmpegContainer = v.blockDownloadFFmpeg(donwloadFFmpeg)
@@ -95,7 +110,9 @@ func (v View) getButtonSelectFile(path string) (filePath *string, button *widget
buttonMessage.TextSize = 16 buttonMessage.TextSize = 16
buttonMessage.TextStyle = fyne.TextStyle{Bold: true} buttonMessage.TextStyle = fyne.TextStyle{Bold: true}
buttonTitle := v.app.GetLocalizerService().GetMessage("choose") buttonTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "choose",
})
var locationURI fyne.ListableURI var locationURI fyne.ListableURI
if len(path) > 0 { if len(path) > 0 {

View File

@@ -8,6 +8,7 @@ import (
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/image/colornames" "golang.org/x/image/colornames"
"image/color" "image/color"
) )
@@ -28,7 +29,9 @@ func (v View) blockDownloadFFmpeg(
var buttonDownloadFFmpeg *widget.Button var buttonDownloadFFmpeg *widget.Button
buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage("download"), func() { buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "download",
}), func() {
fyne.Do(func() { fyne.Do(func() {
buttonDownloadFFmpeg.Disable() buttonDownloadFFmpeg.Disable()
}) })
@@ -44,11 +47,15 @@ func (v View) blockDownloadFFmpeg(
}) })
downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage("downloadFFmpegFromSite") downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "downloadFFmpegFromSite",
})
return container.NewVBox( return container.NewVBox(
canvas.NewLine(colornames.Darkgreen), canvas.NewLine(colornames.Darkgreen),
widget.NewCard(v.app.GetLocalizerService().GetMessage("buttonDownloadFFmpeg"), "", container.NewVBox( widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "buttonDownloadFFmpeg",
}), "", container.NewVBox(
widget.NewRichTextFromMarkdown( widget.NewRichTextFromMarkdown(
downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)", downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)",
), ),

View File

@@ -8,6 +8,7 @@ import (
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/image/colornames" "golang.org/x/image/colornames"
"image/color" "image/color"
) )
@@ -28,7 +29,9 @@ func (v View) blockDownloadFFmpeg(
var buttonDownloadFFmpeg *widget.Button var buttonDownloadFFmpeg *widget.Button
buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage("download"), func() { buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "download",
}), func() {
go func() { go func() {
fyne.Do(func() { fyne.Do(func() {
@@ -44,11 +47,15 @@ func (v View) blockDownloadFFmpeg(
}() }()
}) })
downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage("downloadFFmpegFromSite") downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "downloadFFmpegFromSite",
})
return container.NewVBox( return container.NewVBox(
canvas.NewLine(colornames.Darkgreen), canvas.NewLine(colornames.Darkgreen),
widget.NewCard(v.app.GetLocalizerService().GetMessage("buttonDownloadFFmpeg"), "", container.NewVBox( widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "buttonDownloadFFmpeg",
}), "", container.NewVBox(
widget.NewRichTextFromMarkdown( widget.NewRichTextFromMarkdown(
downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)", downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)",
), ),

2
data/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

7
db/db.go Normal file
View File

@@ -0,0 +1,7 @@
package db
import "errors"
var (
ErrRecordNotFound = errors.New("record not found")
)

View File

@@ -1,10 +1,14 @@
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"
"go.etcd.io/bbolt"
) )
type ViewContract interface { type ViewContract interface {
@@ -13,21 +17,37 @@ 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) {
messageHead := v.app.GetLocalizerService().GetMessage("error") if v.isSetLanguage {
v.isSetLanguage = false
_ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
}
messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
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(err.Error()), widget.NewLabel(messagetText),
), ),
nil, nil,
nil, nil,
@@ -37,3 +57,30 @@ func (v View) PanicError(err error) {
}), }),
)) ))
} }
func (v View) PanicErrorWriteDirectoryData() {
if v.isSetLanguage {
v.isSetLanguage = false
_ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
}
message := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorDatabase",
})
messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "error",
})
v.app.GetWindow().SetContent(container.NewBorder(
container.NewVBox(
widget.NewLabel(messageHead),
widget.NewLabel(message),
),
nil,
nil,
nil,
localizer.LanguageSelectionForm(v.app.GetLocalizerService(), func(lang kernel.Lang) {
v.PanicErrorWriteDirectoryData()
}),
))
}

7
go.mod
View File

@@ -6,13 +6,16 @@ toolchain go1.23.9
require ( require (
fyne.io/fyne/v2 v2.6.1 fyne.io/fyne/v2 v2.6.1
github.com/BurntSushi/toml v1.5.0
github.com/nicksnyder/go-i18n/v2 v2.6.0
github.com/ulikunitz/xz v0.5.12 github.com/ulikunitz/xz v0.5.12
go.etcd.io/bbolt v1.4.0
golang.org/x/image v0.27.0 golang.org/x/image v0.27.0
golang.org/x/text v0.25.0
) )
require ( require (
fyne.io/systray v1.11.0 // indirect fyne.io/systray v1.11.0 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v1.1.0 // indirect github.com/fredbi/uri v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
@@ -31,7 +34,6 @@ require (
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rymdport/portal v0.4.1 // indirect github.com/rymdport/portal v0.4.1 // indirect
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
@@ -40,6 +42,5 @@ require (
github.com/yuin/goldmark v1.7.11 // indirect github.com/yuin/goldmark v1.7.11 // indirect
golang.org/x/net v0.40.0 // indirect golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

4
go.sum
View File

@@ -67,10 +67,14 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo= github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo=
github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=

View File

@@ -8,6 +8,7 @@ import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
"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/setting" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
"github.com/nicksnyder/go-i18n/v2/i18n"
) )
type ConvertorHandlerContract interface { type ConvertorHandlerContract interface {
@@ -60,9 +61,9 @@ func (h ConvertorHandler) MainConvertor() {
} }
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() ffplay, _ := h.convertorRepository.GetPathFfplay()
h.convertorView.SelectFFPath(ffmpeg, ffprobe, ffplay, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg) h.convertorView.SelectFFPath(ffmpeg, ffprobe, ffplay, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
} }
@@ -121,9 +122,9 @@ func (h ConvertorHandler) checkingFFPathUtilities() bool {
if ffplayChecking == false { if ffplayChecking == false {
continue 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) _, _ = h.convertorRepository.SavePathFfplay(item.FFplay)
return true return true
} }
@@ -133,25 +134,31 @@ func (h ConvertorHandler) checkingFFPathUtilities() bool {
func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string, ffplayPath string) error { func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string, ffplayPath 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("errorFFmpeg") errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFmpeg",
})
return errors.New(errorText) return errors.New(errorText)
} }
ffprobeChecking, _ := h.app.GetConvertorService().ChangeFFprobePath(ffprobePath) ffprobeChecking, _ := h.app.GetConvertorService().ChangeFFprobePath(ffprobePath)
if ffprobeChecking == false { if ffprobeChecking == false {
errorText := h.app.GetLocalizerService().GetMessage("errorFFprobe") errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFprobe",
})
return errors.New(errorText) return errors.New(errorText)
} }
ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(ffplayPath) ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(ffplayPath)
if ffplayChecking == false { if ffplayChecking == false {
errorText := h.app.GetLocalizerService().GetMessage("errorFFplay") errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFplay",
})
return errors.New(errorText) 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.convertorRepository.SavePathFfplay(ffplayPath)
h.MainConvertor() h.MainConvertor()

View File

@@ -10,6 +10,7 @@ import (
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"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/ulikunitz/xz" "github.com/ulikunitz/xz"
"io" "io"
"net/http" "net/http"
@@ -29,7 +30,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("downloadRun") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "downloadRun",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -38,7 +41,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("unzipRun") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "unzipRun",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -48,7 +53,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
} }
_ = os.Remove("ffmpeg/ffmpeg.tar.xz") _ = os.Remove("ffmpeg/ffmpeg.tar.xz")
progressMessage.Text = h.app.GetLocalizerService().GetMessage("testFF") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "testFF",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -62,7 +69,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("completedQueue") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "completedQueue",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })

View File

@@ -10,6 +10,7 @@ import (
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"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"
"io" "io"
"net/http" "net/http"
"os" "os"
@@ -29,7 +30,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("downloadRun") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "downloadRun",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -38,7 +41,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("unzipRun") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "unzipRun",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -48,7 +53,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
} }
_ = os.Remove("ffmpeg/ffmpeg.zip") _ = os.Remove("ffmpeg/ffmpeg.zip")
progressMessage.Text = h.app.GetLocalizerService().GetMessage("testFF") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "testFF",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })
@@ -61,7 +68,9 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
return err return err
} }
progressMessage.Text = h.app.GetLocalizerService().GetMessage("completedQueue") progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "completedQueue",
})
fyne.Do(func() { fyne.Do(func() {
progressMessage.Refresh() progressMessage.Refresh()
}) })

View File

@@ -1,32 +1,42 @@
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"
) )
type MainHandler struct { type MainHandler struct {
app kernel.AppContract app kernel.AppContract
convertorHandler ConvertorHandlerContract convertorHandler ConvertorHandlerContract
menuHandler MenuHandlerContract menuHandler MenuHandlerContract
localizerRepository localizer.RepositoryContract
} }
func NewMainHandler( func NewMainHandler(
app kernel.AppContract, app kernel.AppContract,
convertorHandler ConvertorHandlerContract, convertorHandler ConvertorHandlerContract,
menuHandler MenuHandlerContract, menuHandler MenuHandlerContract,
localizerRepository localizer.RepositoryContract,
) *MainHandler { ) *MainHandler {
return &MainHandler{ return &MainHandler{
app: app, app: app,
convertorHandler: convertorHandler, convertorHandler: convertorHandler,
menuHandler: menuHandler, menuHandler: menuHandler,
localizerRepository: localizerRepository,
} }
} }
func (h MainHandler) Start() { func (h MainHandler) Start() {
if h.app.GetLocalizerService().IsStartWithLanguageSelection() { language, err := h.localizerRepository.GetCode()
if err != nil {
err = h.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
if err != nil {
h.menuHandler.LanguageSelection() h.menuHandler.LanguageSelection()
return return
} }
}
_ = h.app.GetLocalizerService().SetCurrentLanguageByCode(language)
h.convertorHandler.MainConvertor() h.convertorHandler.MainConvertor()
} }

View File

@@ -6,6 +6,7 @@ import (
"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" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"github.com/nicksnyder/go-i18n/v2/i18n"
) )
type MenuHandlerContract interface { type MenuHandlerContract interface {
@@ -19,6 +20,7 @@ type MenuHandler struct {
menuView menu.ViewContract menuView menu.ViewContract
menuViewSetting menu.ViewSettingContract menuViewSetting menu.ViewSettingContract
localizerView localizer.ViewContract localizerView localizer.ViewContract
localizerRepository localizer.RepositoryContract
themeService theme.ThemeContract themeService theme.ThemeContract
} }
@@ -28,6 +30,7 @@ func NewMenuHandler(
menuView menu.ViewContract, menuView menu.ViewContract,
menuViewSetting menu.ViewSettingContract, menuViewSetting menu.ViewSettingContract,
localizerView localizer.ViewContract, localizerView localizer.ViewContract,
localizerRepository localizer.RepositoryContract,
themeService theme.ThemeContract, themeService theme.ThemeContract,
) *MenuHandler { ) *MenuHandler {
return &MenuHandler{ return &MenuHandler{
@@ -36,6 +39,7 @@ func NewMenuHandler(
menuView: menuView, menuView: menuView,
menuViewSetting: menuViewSetting, menuViewSetting: menuViewSetting,
localizerView: localizerView, localizerView: localizerView,
localizerRepository: localizerRepository,
themeService: themeService, themeService: themeService,
} }
} }
@@ -48,23 +52,31 @@ func (h MenuHandler) GetMainMenu() *fyne.MainMenu {
} }
func (h MenuHandler) getMenuSettings() *fyne.Menu { func (h MenuHandler) getMenuSettings() *fyne.Menu {
quit := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage("exit"), nil) quit := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "exit",
}), nil)
quit.IsQuit = true quit.IsQuit = true
h.app.GetLocalizerService().AddChangeCallback("exit", func(text string) { h.app.GetLocalizerService().AddChangeCallback("exit", func(text string) {
quit.Label = text quit.Label = text
}) })
settingsSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage("settings"), h.settingsSelection) settingsSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings",
}), h.settingsSelection)
h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) { h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) {
settingsSelection.Label = text settingsSelection.Label = text
}) })
ffPathSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage("changeFFPath"), h.convertorHandler.FfPathSelection) ffPathSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "changeFFPath",
}), h.convertorHandler.FfPathSelection)
h.app.GetLocalizerService().AddChangeCallback("changeFFPath", func(text string) { h.app.GetLocalizerService().AddChangeCallback("changeFFPath", func(text string) {
ffPathSelection.Label = text ffPathSelection.Label = text
}) })
settings := fyne.NewMenu(h.app.GetLocalizerService().GetMessage("settings"), settingsSelection, ffPathSelection, quit) settings := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings",
}), settingsSelection, 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()
@@ -74,22 +86,30 @@ func (h MenuHandler) getMenuSettings() *fyne.Menu {
} }
func (h MenuHandler) getMenuHelp() *fyne.Menu { func (h MenuHandler) getMenuHelp() *fyne.Menu {
about := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage("about"), h.openAbout) about := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "about",
}), h.openAbout)
h.app.GetLocalizerService().AddChangeCallback("about", func(text string) { h.app.GetLocalizerService().AddChangeCallback("about", func(text string) {
about.Label = text about.Label = text
}) })
gratitude := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage("gratitude"), h.menuView.Gratitude) gratitude := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "gratitude",
}), h.menuView.Gratitude)
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("helpFFplay"), h.menuView.HelpFFplay) helpFFplay := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplay",
}), h.menuView.HelpFFplay)
h.app.GetLocalizerService().AddChangeCallback("helpFFplay", func(text string) { h.app.GetLocalizerService().AddChangeCallback("helpFFplay", func(text string) {
helpFFplay.Label = text helpFFplay.Label = text
}) })
help := fyne.NewMenu(h.app.GetLocalizerService().GetMessage("help"), helpFFplay, about, gratitude) help := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "help",
}), helpFFplay, 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()
@@ -101,15 +121,21 @@ func (h MenuHandler) getMenuHelp() *fyne.Menu {
func (h MenuHandler) openAbout() { func (h MenuHandler) openAbout() {
ffmpeg, err := h.convertorHandler.GetFfmpegVersion() ffmpeg, err := h.convertorHandler.GetFfmpegVersion()
if err != nil { if err != nil {
ffmpeg = h.app.GetLocalizerService().GetMessage("errorFFmpegVersion") ffmpeg = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFmpegVersion",
})
} }
ffprobe, err := h.convertorHandler.GetFfprobeVersion() ffprobe, err := h.convertorHandler.GetFfprobeVersion()
if err != nil { if err != nil {
ffprobe = h.app.GetLocalizerService().GetMessage("errorFFprobeVersion") ffprobe = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFprobeVersion",
})
} }
ffplay, err := h.convertorHandler.GetFfplayVersion() ffplay, err := h.convertorHandler.GetFfplayVersion()
if err != nil { if err != nil {
ffplay = h.app.GetLocalizerService().GetMessage("errorFFplayVersion") ffplay = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "errorFFplayVersion",
})
} }
h.menuView.About(ffmpeg, ffprobe, ffplay) h.menuView.About(ffmpeg, ffprobe, ffplay)
@@ -117,13 +143,18 @@ func (h MenuHandler) openAbout() {
func (h MenuHandler) LanguageSelection() { func (h MenuHandler) LanguageSelection() {
h.localizerView.LanguageSelection(func(lang kernel.Lang) { h.localizerView.LanguageSelection(func(lang kernel.Lang) {
_, _ = h.localizerRepository.Save(lang.Code)
h.convertorHandler.MainConvertor() h.convertorHandler.MainConvertor()
}) })
} }
func (h MenuHandler) settingsSelection() { func (h MenuHandler) settingsSelection() {
save := func(setting *menu.SettingForm) error { save := func(setting *menu.SettingForm) error {
err := h.app.GetLocalizerService().SetCurrentLanguage(setting.Language, true) err := h.app.GetLocalizerService().SetCurrentLanguage(setting.Language)
if err != nil {
return err
}
_, err = h.localizerRepository.Save(setting.Language.Code)
if err != nil { if err != nil {
return err return err
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,13 +0,0 @@
package resources
import (
_ "embed"
"fyne.io/fyne/v2"
)
//go:embed icons/logo.png
var iconAppLogo []byte
func IconAppLogoResource() *fyne.StaticResource {
return fyne.NewStaticResource("icon.png", iconAppLogo)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -30,6 +30,7 @@ type App struct {
func NewApp( func NewApp(
metadata *fyne.AppMetadata, metadata *fyne.AppMetadata,
localizerService LocalizerContract,
queue QueueListContract, queue QueueListContract,
ffplayService FFplayContract, ffplayService FFplayContract,
convertorService ConvertorContract, convertorService ConvertorContract,
@@ -37,12 +38,6 @@ func NewApp(
app.SetMetadata(*metadata) app.SetMetadata(*metadata)
a := app.New() a := app.New()
localizerService, err := newLocalizer(a)
if err != nil {
panicErrorLang(a, err)
return nil
}
statusesText := GetBlockProgressbarStatusesText(localizerService) statusesText := GetBlockProgressbarStatusesText(localizerService)
blockProgressbarService := NewBlockProgressbar(statusesText, ffplayService) blockProgressbarService := NewBlockProgressbar(statusesText, ffplayService)
rightTabsService := NewRightTabs(localizerService) rightTabsService := NewRightTabs(localizerService)

View File

@@ -2,11 +2,14 @@ package kernel
import ( import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
) )
func panicErrorLang(a fyne.App, err error) { func PanicErrorLang(err error, metadata *fyne.AppMetadata) {
app.SetMetadata(*metadata)
a := app.New()
window := a.NewWindow("GUI for FFmpeg") window := a.NewWindow("GUI for FFmpeg")
window.SetContent(container.NewVBox( window.SetContent(container.NewVBox(
widget.NewLabel("Произошла ошибка!"), widget.NewLabel("Произошла ошибка!"),

View File

@@ -6,6 +6,7 @@ import (
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
) )
type ItemsToConvertContract interface { type ItemsToConvertContract interface {
@@ -34,23 +35,21 @@ func NewItemsToConvert(itemsContainer *fyne.Container, ffplayService FFplayContr
line := canvas.NewLine(theme.Color(theme.ColorNameFocus)) line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
line.StrokeWidth = 5 line.StrokeWidth = 5
checkboxAutoRemove := widget.NewCheck( checkboxAutoRemove := widget.NewCheck(localizerService.GetMessage(&i18n.LocalizeConfig{
localizerService.GetMessage("autoClearAfterAddingToQueue"), MessageID: "autoClearAfterAddingToQueue",
func(checked bool) { }), func(checked bool) {
ItemsToConvert.isAutoRemove = checked ItemsToConvert.isAutoRemove = checked
}, })
)
checkboxAutoRemove.SetChecked(ItemsToConvert.isAutoRemove) checkboxAutoRemove.SetChecked(ItemsToConvert.isAutoRemove)
localizerService.AddChangeCallback("autoClearAfterAddingToQueue", func(text string) { localizerService.AddChangeCallback("autoClearAfterAddingToQueue", func(text string) {
checkboxAutoRemove.Text = text checkboxAutoRemove.Text = text
}) })
buttonClear := widget.NewButton( buttonClear := widget.NewButton(localizerService.GetMessage(&i18n.LocalizeConfig{
localizerService.GetMessage("clearAll"), MessageID: "clearAll",
func() { }), func() {
ItemsToConvert.clear() ItemsToConvert.clear()
}, })
)
buttonClear.Importance = widget.DangerImportance buttonClear.Importance = widget.DangerImportance
localizerService.AddChangeCallback("clearAll", func(text string) { localizerService.AddChangeCallback("clearAll", func(text string) {
buttonClear.Text = text buttonClear.Text = text

View File

@@ -6,6 +6,7 @@ import (
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
"strconv" "strconv"
"strings" "strings"
@@ -76,7 +77,7 @@ type QueueLayoutItem struct {
} }
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract, rightTabsService RightTabsContract, blockProgressbar *fyne.Container) *QueueLayoutObject { func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract, rightTabsService RightTabsContract, blockProgressbar *fyne.Container) *QueueLayoutObject {
title := widget.NewLabel(localizerService.GetMessage("queue")) title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
title.TextStyle.Bold = true title.TextStyle.Bold = true
localizerService.AddChangeCallback("queue", func(text string) { localizerService.AddChangeCallback("queue", func(text string) {
@@ -221,7 +222,7 @@ func (o QueueLayoutObject) getStatusColor(status StatusContract) color.Color {
} }
func (o QueueLayoutObject) getStatusTitle(status StatusContract) string { func (o QueueLayoutObject) getStatusTitle(status StatusContract) string {
return o.localizerService.GetMessage(status.Name() + "Queue") return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"})
} }
type queueStatistics struct { type queueStatistics struct {
@@ -440,7 +441,7 @@ func newQueueStatistics(messaigeID string, localizerService LocalizerContract) *
count := int64(0) count := int64(0)
title := localizerService.GetMessage(messaigeID) title := localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: messaigeID})
queueStatistics := &queueStatistics{ queueStatistics := &queueStatistics{
widget: checkbox, widget: checkbox,
title: strings.ToLower(title), title: strings.ToLower(title),

View File

@@ -1,28 +1,21 @@
package kernel package kernel
import ( import (
"embed" "github.com/BurntSushi/toml"
"encoding/json" "github.com/nicksnyder/go-i18n/v2/i18n"
"fyne.io/fyne/v2" "golang.org/x/text/cases"
"fyne.io/fyne/v2/lang"
"golang.org/x/text/language" "golang.org/x/text/language"
"golang.org/x/text/language/display"
"path/filepath"
"sort"
) )
//go:embed translations
var translations embed.FS
var supportedLanguages = map[string]Lang{
"ru": {Code: "ru", Title: "Русский"},
"kk": {Code: "kk", Title: "Қазақ Тілі"},
"en": {Code: "en", Title: "English"},
}
type LocalizerContract interface { type LocalizerContract interface {
IsStartWithLanguageSelection() bool
GetMessage(key string, data ...any) string
GetLanguages() []Lang GetLanguages() []Lang
GetCurrentLanguage() Lang GetMessage(localizeConfig *i18n.LocalizeConfig) string
SetCurrentLanguage(selectLang Lang, isSaveSetting bool) error SetCurrentLanguage(lang Lang) error
SetCurrentLanguageByCode(code string) error
GetCurrentLanguage() *CurrentLanguage
AddChangeCallback(messageID string, callback func(text string)) AddChangeCallback(messageID string, callback func(text string))
} }
@@ -31,164 +24,135 @@ type Lang struct {
Title string Title string
} }
type CurrentLanguage struct {
Lang Lang
localizer *i18n.Localizer
localizerDefault *i18n.Localizer
}
type changeCallback struct { type changeCallback struct {
messageID string messageID string
callback func(text string) callback func(text string)
} }
type Localizer struct { type Localizer struct {
setting SettingLanguageContract bundle *i18n.Bundle
currentLang Lang languages []Lang
currentLanguage *CurrentLanguage
changeCallbacks map[int]*changeCallback changeCallbacks map[int]*changeCallback
isStartWithLanguageSelection bool
} }
func newLocalizer(app fyne.App) (*Localizer, error) { func NewLocalizer(directory string, languageDefault language.Tag) (*Localizer, error) {
setting := newSettingLanguage(app) bundle := i18n.NewBundle(languageDefault)
currentLanguage, isLanguageNotSupported := setting.GetLang() bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
localizer := &Localizer{ languages, err := initLanguages(directory, bundle)
setting: setting,
changeCallbacks: map[int]*changeCallback{},
isStartWithLanguageSelection: isLanguageNotSupported,
}
err := localizer.SetCurrentLanguage(currentLanguage, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return localizer, nil localizerDefault := i18n.NewLocalizer(bundle, languageDefault.String())
return &Localizer{
bundle: bundle,
languages: languages,
currentLanguage: &CurrentLanguage{
Lang: Lang{
Code: languageDefault.String(),
Title: cases.Title(languageDefault).String(display.Self.Name(languageDefault)),
},
localizer: localizerDefault,
localizerDefault: localizerDefault,
},
changeCallbacks: map[int]*changeCallback{},
}, nil
} }
func (l *Localizer) IsStartWithLanguageSelection() bool { func initLanguages(directory string, bundle *i18n.Bundle) ([]Lang, error) {
return l.isStartWithLanguageSelection var languages []Lang
}
func (l *Localizer) GetMessage(key string, data ...any) string { files, err := filepath.Glob(directory + "/active.*.toml")
return lang.L(key, data...)
}
func (l *Localizer) GetLanguages() []Lang {
return getLanguages()
}
func (l *Localizer) GetCurrentLanguage() Lang {
return l.currentLang
}
func (l *Localizer) SetCurrentLanguage(selectLang Lang, isSaveSetting bool) error {
l.currentLang = selectLang
translationsData, err := l.getTranslations(selectLang)
if err != nil { if err != nil {
return err return nil, err
} }
for _, file := range files {
name := lang.SystemLocale().LanguageString() lang, err := bundle.LoadMessageFile(file)
err = lang.AddTranslations(fyne.NewStaticResource(name+".json", translationsData))
if err != nil { if err != nil {
return err return nil, err
}
title := cases.Title(lang.Tag).String(display.Self.Name(lang.Tag))
languages = append(languages, Lang{Code: lang.Tag.String(), Title: title})
} }
if isSaveSetting { sort.Sort(languagesSort(languages))
l.setting.SetLang(selectLang)
}
return languages, nil
}
func (l Localizer) GetLanguages() []Lang {
return l.languages
}
func (l Localizer) GetMessage(localizeConfig *i18n.LocalizeConfig) string {
message, err := l.GetCurrentLanguage().localizer.Localize(localizeConfig)
if err != nil {
message, err = l.GetCurrentLanguage().localizerDefault.Localize(localizeConfig)
if err != nil {
return err.Error()
}
}
return message
}
func (l Localizer) SetCurrentLanguage(lang Lang) error {
l.currentLanguage.Lang = lang
l.currentLanguage.localizer = i18n.NewLocalizer(l.bundle, lang.Code)
l.eventSetCurrentLanguage() l.eventSetCurrentLanguage()
return nil return nil
} }
func (l *Localizer) AddChangeCallback(messageID string, callback func(text string)) { func (l Localizer) SetCurrentLanguageByCode(code string) error {
lang, err := language.Parse(code)
if err != nil {
return err
}
title := cases.Title(lang).String(display.Self.Name(lang))
return l.SetCurrentLanguage(Lang{Code: lang.String(), Title: title})
}
func (l Localizer) GetCurrentLanguage() *CurrentLanguage {
return l.currentLanguage
}
func (l Localizer) AddChangeCallback(messageID string, callback func(text string)) {
l.changeCallbacks[len(l.changeCallbacks)] = &changeCallback{messageID: messageID, callback: callback} l.changeCallbacks[len(l.changeCallbacks)] = &changeCallback{messageID: messageID, callback: callback}
} }
func (l *Localizer) eventSetCurrentLanguage() { func (l Localizer) eventSetCurrentLanguage() {
for _, changeCallback := range l.changeCallbacks { for _, changeCallback := range l.changeCallbacks {
text := l.GetMessage(changeCallback.messageID) text := l.GetMessage(&i18n.LocalizeConfig{MessageID: changeCallback.messageID})
changeCallback.callback(text) changeCallback.callback(text)
} }
} }
func (l *Localizer) getTranslations(language Lang) ([]byte, error) { type languagesSort []Lang
baseJson, err := translations.ReadFile("translations/base." + language.Code + ".json")
if err != nil {
return nil, err
}
appJson, err := translations.ReadFile("translations/app." + language.Code + ".json")
if err != nil {
return nil, err
}
return l.mergeTranslations(baseJson, appJson) func (l languagesSort) Len() int { return len(l) }
func (l languagesSort) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
func (l languagesSort) Less(i, j int) bool {
return languagePriority(l[i]) < languagePriority(l[j])
} }
func languagePriority(l Lang) int {
priority := 0
func (l *Localizer) mergeTranslations(baseJson []byte, appJson []byte) ([]byte, error) { switch l.Code {
base := map[string]interface{}{} case "ru":
custom := map[string]interface{}{} priority = -3
err := json.Unmarshal(baseJson, &base) case "kk":
if err != nil { priority = -2
return nil, err case "en":
} priority = -1
err = json.Unmarshal(appJson, &custom)
if err != nil {
return nil, err
} }
for k, v := range custom { return priority
base[k] = v
}
return json.Marshal(base)
}
func getLanguages() []Lang {
items := []Lang{}
for _, item := range supportedLanguages {
items = append(items, item)
}
return items
}
type SettingLanguageContract interface {
GetLang() (currentLang Lang, isLanguageNotSupported bool)
SetLang(language Lang)
}
type SettingLanguage struct {
app fyne.App
}
func newSettingLanguage(app fyne.App) *SettingLanguage {
return &SettingLanguage{
app: app,
}
}
func (s *SettingLanguage) GetLang() (currentLang Lang, isLanguageNotSupported bool) {
languageCode := s.app.Preferences().String("language")
currentLang = supportedLanguages["ru"]
if languageCode == "" {
languageTag, err := language.Parse(lang.SystemLocale().LanguageString())
if err != nil {
return currentLang, true
}
base, _ := languageTag.Base()
languageCode = base.String()
}
if findLang, ok := findSupportedLanguage(languageCode); ok {
return findLang, false
}
return currentLang, true
}
func (s *SettingLanguage) SetLang(language Lang) {
s.app.Preferences().SetString("language", language.Code)
}
func findSupportedLanguage(code string) (Lang, bool) {
lang, ok := supportedLanguages[code]
return lang, ok
} }

View File

@@ -8,6 +8,7 @@ import (
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
"io" "io"
"regexp" "regexp"
@@ -208,7 +209,9 @@ func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
if isProcessCompleted == false { if isProcessCompleted == false {
if len(errorText) == 0 { if len(errorText) == 0 {
errorText = p.localizerService.GetMessage("errorConverter") errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "errorConverter",
})
} }
return errors.New(errorText) return errors.New(errorText)
} }
@@ -224,9 +227,15 @@ type BlockProgressbarStatusesText struct {
func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText { func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText {
statusesText := &BlockProgressbarStatusesText{ statusesText := &BlockProgressbarStatusesText{
inProgress: localizerService.GetMessage("inProgressQueue"), inProgress: localizerService.GetMessage(&i18n.LocalizeConfig{
completed: localizerService.GetMessage("completedQueue"), MessageID: "inProgressQueue",
error: localizerService.GetMessage("errorQueue"), }),
completed: localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "completedQueue",
}),
error: localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "errorQueue",
}),
} }
localizerService.AddChangeCallback("inProgressQueue", func(text string) { localizerService.AddChangeCallback("inProgressQueue", func(text string) {

View File

@@ -3,6 +3,7 @@ package kernel
import ( import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"github.com/nicksnyder/go-i18n/v2/i18n"
) )
type RightTabsContract interface { type RightTabsContract interface {
@@ -25,13 +26,13 @@ type RightTabs struct {
func NewRightTabs(localizerService LocalizerContract) *RightTabs { func NewRightTabs(localizerService LocalizerContract) *RightTabs {
addedFilesContainer := container.NewVBox() addedFilesContainer := container.NewVBox()
addedFilesTab := container.NewTabItem(localizerService.GetMessage("addedFilesTitle"), addedFilesContainer) addedFilesTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "addedFilesTitle"}), addedFilesContainer)
localizerService.AddChangeCallback("addedFilesTitle", func(text string) { localizerService.AddChangeCallback("addedFilesTitle", func(text string) {
addedFilesTab.Text = text addedFilesTab.Text = text
}) })
fileQueueContainer := container.NewVBox() fileQueueContainer := container.NewVBox()
fileQueueTab := container.NewTabItem(localizerService.GetMessage("fileQueueTitle"), fileQueueContainer) fileQueueTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "fileQueueTitle"}), fileQueueContainer)
localizerService.AddChangeCallback("fileQueueTitle", func(text string) { localizerService.AddChangeCallback("fileQueueTitle", func(text string) {
fileQueueTab.Text = text fileQueueTab.Text = text
}) })

View File

@@ -1,143 +0,0 @@
{
"AlsoUsedProgram": "The program also uses:",
"about": "About",
"aboutText": "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself.",
"addedFilesTitle": "Added files",
"autoClearAfterAddingToQueue": "Auto-clear after adding to queue",
"buttonDownloadFFmpeg": "Download FFmpeg automatically",
"buttonForSelectedDirTitle": "Save to folder:",
"cancel": "Cancel",
"changeFFPath": "FFmpeg, FFprobe and FFplay",
"changeLanguage": "Change language",
"checkboxOverwriteOutputFilesTitle": "Allow file to be overwritten",
"choose": "choose",
"clearAll": "Clear List",
"completedQueue": "Completed",
"converterVideoFilesSubmitTitle": "Convert",
"converterVideoFilesTitle": "Video, audio and picture converter",
"download": "Download",
"downloadFFmpegFromSite": "Will be downloaded from the site:",
"downloadRun": "Downloading...",
"dragAndDropFiles": "drag and drop files",
"encoderGroupAudio": "Audio",
"encoderGroupImage": "Images",
"encoderGroupVideo": "Video",
"encoder_apng": "APNG image",
"encoder_bmp": "BMP image",
"encoder_flv": "FLV",
"encoder_gif": "GIF image",
"encoder_h264_nvenc": "H.264 with NVIDIA support",
"encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)",
"encoder_libshine": "libshine MP3 (MPEG audio layer 3)",
"encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)",
"encoder_libvpx": "libvpx VP8 (codec vp8)",
"encoder_libvpx-vp9": "libvpx VP9 (codec vp9)",
"encoder_libwebp": "libwebp WebP image",
"encoder_libwebp_anim": "libwebp_anim WebP image",
"encoder_libx264": "H.264 libx264",
"encoder_libx265": "H.265 libx265",
"encoder_libxvid": "libxvidcore MPEG-4 part 2",
"encoder_mjpeg": "MJPEG (Motion JPEG)",
"encoder_mp2": "MP2 (MPEG audio layer 2)",
"encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)",
"encoder_mpeg1video": "MPEG-1",
"encoder_mpeg2video": "MPEG-2",
"encoder_mpeg4": "MPEG-4 part 2",
"encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3",
"encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2",
"encoder_msvideo1": "Microsoft Video-1",
"encoder_png": "PNG image",
"encoder_qtrle": "QuickTime Animation (RLE) video",
"encoder_sgi": "SGI image",
"encoder_tiff": "TIFF image",
"encoder_wmav1": "Windows Media Audio 1",
"encoder_wmav2": "Windows Media Audio 2",
"encoder_wmv1": "Windows Media Video 7",
"encoder_wmv2": "Windows Media Video 8",
"encoder_xbm": "XBM (X BitMap) image",
"error": "An error has occurred!",
"errorConverter": "Couldn't convert video",
"errorDragAndDropFile": "Not all files were added",
"errorFFmpeg": "this is not FFmpeg",
"errorFFmpegVersion": "Could not determine FFmpeg version",
"errorFFplay": "this is not FFplay",
"errorFFplayVersion": "Could not determine FFplay version",
"errorFFprobe": "this is not FFprobe",
"errorFFprobeVersion": "Failed to determine FFprobe version",
"errorNoFilesAddedForConversion": "There are no files to convert",
"errorQueue": "Error",
"errorSelectedEncoder": "Converter not selected",
"errorSelectedFolderSave": "No save folder selected!",
"errorSelectedFormat": "File extension not selected",
"exit": "Exit",
"ffmpegLGPL": "This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**.",
"ffmpegTrademark": "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project.",
"fileForConversionTitle": "File:",
"fileQueueTitle": "Queue",
"formPreset": "Preset",
"gratitude": "Gratitude",
"gratitudeText": "I sincerely thank you for your invaluable\n\r and timely assistance:",
"help": "Help",
"helpFFplay": "FFplay Player Keys",
"helpFFplayActivateFrameStepMode": "Activate frame-by-frame mode.",
"helpFFplayCycleVideoFiltersOrShowModes": "A cycle of video filters or display modes.",
"helpFFplayDecreaseVolume": "Decrease the volume.",
"helpFFplayDescription": "Description",
"helpFFplayDoubleClickLeftMouseButton": "double click\nleft mouse button",
"helpFFplayIncreaseVolume": "Increase the volume.",
"helpFFplayKeyDown": "down",
"helpFFplayKeyHoldS": "hold S",
"helpFFplayKeyLeft": "left",
"helpFFplayKeyRight": "right",
"helpFFplayKeySpace": "SPACE",
"helpFFplayKeyUp": "up",
"helpFFplayKeys": "Keys",
"helpFFplayPause": "Pause or continue playing.",
"helpFFplayQuit": "Close the player.",
"helpFFplaySeekBForward10Minutes": "Fast forward 10 minutes.",
"helpFFplaySeekBForward1Minute": "Fast forward 1 minute.",
"helpFFplaySeekBackward10Minutes": "Rewind 10 minutes.",
"helpFFplaySeekBackward10Seconds": "Rewind 10 seconds.",
"helpFFplaySeekBackward1Minute": "Rewind 1 minute.",
"helpFFplaySeekForward10Seconds": "Fast forward 10 seconds.",
"helpFFplayToggleFullScreen": "Switch to full screen or exit full screen.",
"helpFFplayToggleMute": "Mute or unmute.",
"inProgressQueue": "In Progress",
"languageSelectionFormHead": "Switch language",
"languageSelectionHead": "Choose language",
"licenseLink": "License information",
"licenseLinkOther": "Licenses from other products used in the program",
"menuSettingsLanguage": "Language",
"menuSettingsTheme": "Theme",
"or": "or",
"parameterCheckbox": "Enable option",
"pathToFfmpeg": "Path to FFmpeg:",
"pathToFfplay": "Path to FFplay:",
"pathToFfprobe": "Path to FFprobe:",
"preset_fast": "fast (slower than \"faster\", but the file will weigh less)",
"preset_faster": "faster (slower than \"veryfast\", but the file will weigh less)",
"preset_medium": "medium (slower than \"fast\", but the file will weigh less)",
"preset_placebo": "placebo (not recommended)",
"preset_slow": "slow (slower than \"medium\", but the file will weigh less)",
"preset_slower": "slower (slower than \"slow\", but the file will weigh less)",
"preset_superfast": "superfast (slower than \"ultrafast\", but the file will weigh less)",
"preset_ultrafast": "ultrafast (fast, but the file will weigh a lot)",
"preset_veryfast": "veryfast (slower than \"superfast\", but the file will weigh less)",
"preset_veryslow": "veryslow (slower than \"slower\", but the file will weigh less)",
"programmLink": "Project website",
"programmVersion": "**Program version:** {{.Version}}",
"queue": "Queue",
"save": "Save",
"selectEncoder": "Encoder:",
"selectFFPathTitle": "Specify the path to FFmpeg and FFprobe",
"selectFormat": "File extension:",
"settings": "Settings",
"testFF": "Checking FFmpeg for serviceability...",
"themesNameDark": "Dark",
"themesNameDefault": "Default",
"themesNameLight": "Light",
"titleDownloadLink": "You can download it from here",
"total": "Total",
"unzipRun": "Unpacked...",
"waitingQueue": "Waiting"
}

View File

@@ -1,143 +0,0 @@
{
"AlsoUsedProgram": "Бағдарлама сонымен қатар пайдаланады:",
"about": "Бағдарлама туралы",
"aboutText": "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін.",
"addedFilesTitle": "Қосылған файлдар",
"autoClearAfterAddingToQueue": "Кезекке қосқаннан кейін тазалаңыз",
"buttonDownloadFFmpeg": "FFmpeg автоматты түрде жүктеп алыңыз",
"buttonForSelectedDirTitle": "Қалтаға сақтаңыз:",
"cancel": "Болдырмау",
"changeFFPath": "FFmpeg, FFprobe және FFplay",
"changeLanguage": "Тілді өзгерту",
"checkboxOverwriteOutputFilesTitle": "Файлды қайта жазуға рұқсат беріңіз",
"choose": "таңдау",
"clearAll": "Тізімді өшіру",
"completedQueue": "Дайын",
"converterVideoFilesSubmitTitle": "Файлды түрлендіру",
"converterVideoFilesTitle": "Бейне, аудио және суретті түрлендіргіш",
"download": "Жүктеп алу",
"downloadFFmpegFromSite": "Сайттан жүктеледі:",
"downloadRun": "Жүктеп алынуда...",
"dragAndDropFiles": "файлдарды сүйреп апарыңыз",
"encoderGroupAudio": "Аудио",
"encoderGroupImage": "Суреттер",
"encoderGroupVideo": "Бейне",
"encoder_apng": "APNG image",
"encoder_bmp": "BMP image",
"encoder_flv": "FLV",
"encoder_gif": "GIF image",
"encoder_h264_nvenc": "NVIDIA қолдауымен H.264",
"encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)",
"encoder_libshine": "libshine MP3 (MPEG audio layer 3)",
"encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)",
"encoder_libvpx": "libvpx VP8 (codec vp8)",
"encoder_libvpx-vp9": "libvpx VP9 (codec vp9)",
"encoder_libwebp": "libwebp WebP image",
"encoder_libwebp_anim": "libwebp_anim WebP image",
"encoder_libx264": "H.264 libx264",
"encoder_libx265": "H.265 libx265",
"encoder_libxvid": "libxvidcore MPEG-4 part 2",
"encoder_mjpeg": "MJPEG (Motion JPEG)",
"encoder_mp2": "MP2 (MPEG audio layer 2)",
"encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)",
"encoder_mpeg1video": "MPEG-1",
"encoder_mpeg2video": "MPEG-2",
"encoder_mpeg4": "MPEG-4 part 2",
"encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3",
"encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2",
"encoder_msvideo1": "Microsoft Video-1",
"encoder_png": "PNG image",
"encoder_qtrle": "QuickTime Animation (RLE) video",
"encoder_sgi": "SGI image",
"encoder_tiff": "TIFF image",
"encoder_wmav1": "Windows Media Audio 1",
"encoder_wmav2": "Windows Media Audio 2",
"encoder_wmv1": "Windows Media Video 7",
"encoder_wmv2": "Windows Media Video 8",
"encoder_xbm": "XBM (X BitMap) image",
"error": "Қате орын алды!",
"errorConverter": "Бейнені түрлендіру мүмкін болмады",
"errorDragAndDropFile": "Барлық файлдар қосылмаған",
"errorFFmpeg": "бұл FFmpeg емес",
"errorFFmpegVersion": "FFmpeg нұсқасын анықтау мүмкін болмады",
"errorFFplay": "бұл FFplay емес",
"errorFFplayVersion": "FFplay нұсқасын анықтау мүмкін болмады",
"errorFFprobe": "бұл FFprobe емес",
"errorFFprobeVersion": "FFprobe нұсқасын анықтау мүмкін болмады",
"errorNoFilesAddedForConversion": "Түрлендіруге арналған файлдар жоқ",
"errorQueue": "Қате",
"errorSelectedEncoder": "Түрлендіргіш таңдалмаған",
"errorSelectedFolderSave": "Сақтау қалтасы таңдалмаған!",
"errorSelectedFormat": "Файл кеңейтімі таңдалмаған",
"exit": "Шығу",
"ffmpegLGPL": "Бұл бағдарламалық құрал **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)** астында **FFmpeg** жобасының кітапханаларын пайдаланады.",
"ffmpegTrademark": "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын жасаушы **[Fabrice Bellard](http://bellard.org/)** сауда белгісі.",
"fileForConversionTitle": "Файл:",
"fileQueueTitle": "Кезек",
"formPreset": "Алдын ала орнатылған",
"gratitude": "Алғыс",
"gratitudeText": "Сізге баға жетпес және уақтылы көмектескеніңіз\n\r үшін шын жүректен алғыс айтамын:",
"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": "Орындалуда",
"languageSelectionFormHead": "Тілді ауыстыру",
"languageSelectionHead": "Тілді таңдаңыз",
"licenseLink": "Лицензия туралы ақпарат",
"licenseLinkOther": "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары",
"menuSettingsLanguage": "Тіл",
"menuSettingsTheme": "Тақырып",
"or": "немесе",
"parameterCheckbox": "Опцияны қосу",
"pathToFfmpeg": "FFmpeg жол:",
"pathToFfplay": "FFplay жол:",
"pathToFfprobe": "FFprobe жол:",
"preset_fast": "fast («faster» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_faster": "faster («veryfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_medium": "medium («fast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_placebo": "placebo (ұсынылмайды)",
"preset_slow": "slow («medium» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_slower": "slower («slow» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_superfast": "superfast («ultrafast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_ultrafast": "ultrafast (жылдам, бірақ файлдың салмағы көп болады)",
"preset_veryfast": "veryfast («superfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"preset_veryslow": "veryslow («slower» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)",
"programmLink": "Жобаның веб-сайты",
"programmVersion": "**Бағдарлама нұсқасы:** {{.Version}}",
"queue": "Кезек",
"save": "Сақтау",
"selectEncoder": "Кодировщик:",
"selectFFPathTitle": "FFmpeg және FFprobe жолын көрсетіңіз",
"selectFormat": "Файл кеңейтімі:",
"settings": "Параметрлер",
"testFF": "FFmpeg функционалдығы тексерілуде...",
"themesNameDark": "Қараңғы тақырып",
"themesNameDefault": "Әдепкі бойынша",
"themesNameLight": "Жеңіл тақырып",
"titleDownloadLink": "Сіз оны осы жерден жүктей аласыз",
"total": "Барлығы",
"unzipRun": "Орамнан шығарылуда...",
"waitingQueue": "Күту"
}

View File

@@ -1,143 +0,0 @@
{
"AlsoUsedProgram": "Также в программе используется:",
"about": "О программе",
"aboutText": "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg.",
"addedFilesTitle": "Добавленные файлы",
"autoClearAfterAddingToQueue": "Очищать после добавления в очередь",
"buttonDownloadFFmpeg": "Скачать автоматически FFmpeg",
"buttonForSelectedDirTitle": "Сохранить в папку:",
"cancel": "Отмена",
"changeFFPath": "FFmpeg, FFprobe и FFplay",
"changeLanguage": "Поменять язык",
"checkboxOverwriteOutputFilesTitle": "Разрешить перезаписать файл",
"choose": "выбрать",
"clearAll": "Очистить список",
"completedQueue": "Готово",
"converterVideoFilesSubmitTitle": "Конвертировать",
"converterVideoFilesTitle": "Конвертер видео, аудио и картинок",
"download": "Скачать",
"downloadFFmpegFromSite": "Будет скачано с сайта:",
"downloadRun": "Скачивается...",
"dragAndDropFiles": "перетащить файлы",
"encoderGroupAudio": "Аудио",
"encoderGroupImage": "Картинки",
"encoderGroupVideo": "Видео",
"encoder_apng": "APNG image",
"encoder_bmp": "BMP image",
"encoder_flv": "FLV",
"encoder_gif": "GIF image",
"encoder_h264_nvenc": "H.264 с поддержкой NVIDIA",
"encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)",
"encoder_libshine": "libshine MP3 (MPEG audio layer 3)",
"encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)",
"encoder_libvpx": "libvpx VP8 (codec vp8)",
"encoder_libvpx-vp9": "libvpx VP9 (codec vp9)",
"encoder_libwebp": "libwebp WebP image",
"encoder_libwebp_anim": "libwebp_anim WebP image",
"encoder_libx264": "H.264 libx264",
"encoder_libx265": "H.265 libx265",
"encoder_libxvid": "libxvidcore MPEG-4 part 2",
"encoder_mjpeg": "MJPEG (Motion JPEG)",
"encoder_mp2": "MP2 (MPEG audio layer 2)",
"encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)",
"encoder_mpeg1video": "MPEG-1",
"encoder_mpeg2video": "MPEG-2",
"encoder_mpeg4": "MPEG-4 part 2",
"encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3",
"encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2",
"encoder_msvideo1": "Microsoft Video-1",
"encoder_png": "PNG image",
"encoder_qtrle": "QuickTime Animation (RLE) video",
"encoder_sgi": "SGI image",
"encoder_tiff": "TIFF image",
"encoder_wmav1": "Windows Media Audio 1",
"encoder_wmav2": "Windows Media Audio 2",
"encoder_wmv1": "Windows Media Video 7",
"encoder_wmv2": "Windows Media Video 8",
"encoder_xbm": "XBM (X BitMap) image",
"error": "Произошла ошибка!",
"errorConverter": "не смогли отконвертировать видео",
"errorDragAndDropFile": "Не все файлы добавились",
"errorFFmpeg": "это не FFmpeg",
"errorFFmpegVersion": "Не смогли определить версию FFmpeg",
"errorFFplay": "это не FFplay",
"errorFFplayVersion": "Не смогли определить версию FFplay",
"errorFFprobe": "это не FFprobe",
"errorFFprobeVersion": "Не смогли определить версию FFprobe",
"errorNoFilesAddedForConversion": "Нет файлов для конвертации",
"errorQueue": "Ошибка",
"errorSelectedEncoder": "Конвертер не выбран",
"errorSelectedFolderSave": "Папка для сохранения не выбрана!",
"errorSelectedFormat": "Расширение файла не выбрана",
"exit": "Выход",
"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)**.",
"fileForConversionTitle": "Файл:",
"fileQueueTitle": "Очередь",
"formPreset": "Предустановка",
"gratitude": "Благодарность",
"gratitudeText": "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:",
"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": "Выполняется",
"languageSelectionFormHead": "Переключить язык",
"languageSelectionHead": "Выберите язык",
"licenseLink": "Сведения о лицензии",
"licenseLinkOther": "Лицензии от других продуктов, которые используются в программе",
"menuSettingsLanguage": "Язык",
"menuSettingsTheme": "Тема",
"or": "или",
"parameterCheckbox": "Включить параметр",
"pathToFfmpeg": "Путь к FFmpeg:",
"pathToFfplay": "Путь к FFplay:",
"pathToFfprobe": "Путь к FFprobe:",
"preset_fast": "fast (медленней чем faster, но будет файл и меньше весить)",
"preset_faster": "faster (медленней чем veryfast, но будет файл и меньше весить)",
"preset_medium": "medium (медленней чем fast, но будет файл и меньше весить)",
"preset_placebo": "placebo (не рекомендуется)",
"preset_slow": "slow (медленней чем medium, но будет файл и меньше весить)",
"preset_slower": "slower (медленней чем slow, но будет файл и меньше весить)",
"preset_superfast": "superfast (медленней чем ultrafast, но будет файл и меньше весить)",
"preset_ultrafast": "ultrafast (быстро, но файл будет много весить)",
"preset_veryfast": "veryfast (медленней чем superfast, но будет файл и меньше весить)",
"preset_veryslow": "veryslow (медленней чем slower, но будет файл и меньше весить)",
"programmLink": "Сайт проекта",
"programmVersion": "**Версия программы:** {{.Version}}",
"queue": "Очередь",
"save": "Сохранить",
"selectEncoder": "Кодировщик:",
"selectFFPathTitle": "Укажите путь к FFmpeg и к FFprobe",
"selectFormat": "Расширение файла:",
"settings": "Настройки",
"testFF": "Проверка FFmpeg на работоспособность...",
"themesNameDark": "Тёмная",
"themesNameDefault": "По умолчанию",
"themesNameLight": "Светлая",
"titleDownloadLink": "Скачать можно от сюда",
"total": "Всего",
"unzipRun": "Распаковывается...",
"waitingQueue": "В очереди"
}

View File

@@ -1,45 +0,0 @@
{
"Advanced": "Advanced",
"Cancel": "Cancel",
"Confirm": "Confirm",
"Copy": "Copy",
"Create Folder": "Create Folder",
"Cut": "Cut",
"Enter filename": "Enter filename",
"Error": "Error",
"Favourites": "Favourites",
"File": "File",
"Folder": "Folder",
"New Folder": "New Folder",
"No": "No",
"OK": "OK",
"Open": "Open",
"Paste": "Paste",
"Quit": "Quit",
"Redo": "Redo",
"Save": "Save",
"Select all": "Select all",
"Show Hidden Files": "Show Hidden Files",
"Undo": "Undo",
"Yes": "Yes",
"file.name": {
"other": "Name"
},
"file.parent": {
"other": "Parent"
},
"friday": "Friday",
"friday.short": "Fri",
"monday": "Monday",
"monday.short": "Mon",
"saturday": "Saturday",
"saturday.short": "Sat",
"sunday": "Sunday",
"sunday.short": "Sun",
"thursday": "Thursday",
"thursday.short": "Thu",
"tuesday": "Tuesday",
"tuesday.short": "Tue",
"wednesday": "Wednesday",
"wednesday.short": "Wed"
}

View File

@@ -1,45 +0,0 @@
{
"Advanced": "Кеңейтілген",
"Cancel": "Бас тарту",
"Confirm": "Растау",
"Copy": "Көшіру",
"Create Folder": "Қалта жасау",
"Cut": "Кесу",
"Enter filename": "Файл атауын енгізіңіз",
"Error": "Қате",
"Favourites": "Таңдаулылар",
"File": "Файл",
"Folder": "Қалта",
"New Folder": "Жаңа қалта",
"No": "Жоқ",
"OK": "ОК",
"Open": "Ашу",
"Paste": "Кірістіру",
"Quit": "Шығу",
"Redo": "Қайталау",
"Save": "Сақтау",
"Select all": "Барлығын таңдаңыз",
"Show Hidden Files": "Жасырын файлдарды көрсету",
"Undo": "Бас тарту",
"Yes": "Иә",
"file.name": {
"other": "Аты"
},
"file.parent": {
"other": "Жоғары"
},
"friday": "Жұма",
"friday.short": "Жұ",
"monday": "Дүйсенбі",
"monday.short": "Дү",
"saturday": "Сенбі",
"saturday.short": "Сен",
"sunday": "Жексенбі",
"sunday.short": "Же",
"thursday": "Сейсенбі",
"thursday.short": "Се",
"tuesday": "Бейсенбі",
"tuesday.short": "Бе",
"wednesday": "Сәрсенбі",
"wednesday.short": "Сә"
}

View File

@@ -1,45 +0,0 @@
{
"Advanced": "Расширенные",
"Cancel": "Отмена",
"Confirm": "Подтвердить",
"Copy": "Копировать",
"Create Folder": "Создать папку",
"Cut": "Вырезать",
"Enter filename": "Введите имя файла",
"Error": "Ошибка",
"Favourites": "Избранное",
"File": "Файл",
"Folder": "Папка",
"New Folder": "Новая папка",
"No": "Нет",
"OK": "ОК",
"Open": "Открыть",
"Paste": "Вставить",
"Quit": "Выйти",
"Redo": "Повторить",
"Save": "Сохранить",
"Select all": "Выбрать всё",
"Show Hidden Files": "Показать скрытые файлы",
"Undo": "Отменить",
"Yes": "Да",
"file.name": {
"other": "Имя"
},
"file.parent": {
"other": "Вверх"
},
"friday": "Пятница",
"friday.short": "Пт",
"monday": "Понедельник",
"monday.short": "Пн",
"saturday": "Суббота",
"saturday.short": "Сб",
"sunday": "Воскресенье",
"sunday.short": "Вс",
"thursday": "Вторник",
"thursday.short": "Вт",
"tuesday": "Четверг",
"tuesday.short": "Чт",
"wednesday": "Среда",
"wednesday.short": "Ср"
}

1
languages/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
translate.*.toml

571
languages/active.en.toml Normal file
View File

@@ -0,0 +1,571 @@
[AlsoUsedProgram]
hash = "sha1-a72be72e7808bb8a0144ed7a93acb29c568b1ed4"
other = "The program also uses:"
[about]
hash = "sha1-3da0b9ef719fd707f443ac00404447f29445976f"
other = "About"
[aboutText]
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
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]
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
other = "Download FFmpeg automatically"
[buttonForSelectedDirTitle]
hash = "sha1-8cbe5c67bcf89e4624635a79cbea104227faedda"
other = "Save to folder:"
[cancel]
hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
other = "Cancel"
[changeFFPath]
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
other = "FFmpeg, FFprobe and FFplay"
[changeLanguage]
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
other = "Change language"
[checkboxOverwriteOutputFilesTitle]
hash = "sha1-5860124bb781e7ef680f573fa93977e96328d4e7"
other = "Allow file to be overwritten"
[choose]
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
other = "choose"
[clearAll]
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
other = "Clear List"
[completedQueue]
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
other = "Completed"
[converterVideoFilesSubmitTitle]
hash = "sha1-7ac460f3c24c9952082f2db6e4d62f752598709c"
other = "Convert"
[converterVideoFilesTitle]
hash = "sha1-1ab29597cc9dfefab08e54ea5442e7ffa15f0394"
other = "Video, audio and picture converter"
[download]
hash = "sha1-fe8f79f29da457de2f6bc9531de6e536e0c426ad"
other = "Download"
[downloadFFmpegFromSite]
hash = "sha1-0889c95aa3a8659d8d903b4dab7097699c4d8aa4"
other = "Will be downloaded from the site:"
[downloadRun]
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
other = "Downloading..."
[dragAndDropFiles]
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
other = "drag and drop files"
[encoderGroupAudio]
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
other = "Audio"
[encoderGroupImage]
hash = "sha1-a7e528bc7ac9538aec87d1593c38b80be95d4745"
other = "Images"
[encoderGroupVideo]
hash = "sha1-8e7b9894c7ef0f57ac0bf910f6a8aac1c8a53683"
other = "Video"
[encoder_apng]
hash = "sha1-1cbd9abfef96d5614a7e569161b41bd6ad87bbaf"
other = "APNG image"
[encoder_bmp]
hash = "sha1-e0b9c16b016961a5abdc2217e8ffd1ba7ddebc40"
other = "BMP image"
[encoder_flv]
hash = "sha1-3602bbf1cc90e48254f81975c7879b5fc0c4d602"
other = "FLV"
[encoder_gif]
hash = "sha1-d092a779172291b5215aa095390a5b11659128a4"
other = "GIF image"
[encoder_h264_nvenc]
hash = "sha1-169389f8c4a2518410159c363378ab5c978c32e5"
other = "H.264 with NVIDIA support"
[encoder_libmp3lame]
hash = "sha1-cd2c8d6f246c8bc18554b7105cb50b78d3cb2b98"
other = "libmp3lame MP3 (MPEG audio layer 3)"
[encoder_libshine]
hash = "sha1-891d56c85857e5d83ef5a1fe077c1f1540788f49"
other = "libshine MP3 (MPEG audio layer 3)"
[encoder_libtwolame]
hash = "sha1-b2f53be810b74edc3c454ac75de7ddecfee322ca"
other = "libtwolame MP2 (MPEG audio layer 2)"
[encoder_libvpx]
hash = "sha1-b85c923aecfb48de0e87e71b6a21bfc2c547c70e"
other = "libvpx VP8 (codec vp8)"
[encoder_libvpx-vp9]
hash = "sha1-3106417bd89bee87daa691e87614caf78cb934fe"
other = "libvpx VP9 (codec vp9)"
[encoder_libwebp]
hash = "sha1-1d590d47d46f7880246061fce0e0de6d743db39e"
other = "libwebp WebP image"
[encoder_libwebp_anim]
hash = "sha1-f141a9c8f23d79c13d44c30d8f34e05b363771ad"
other = "libwebp_anim WebP image"
[encoder_libx264]
hash = "sha1-6d764ac459c0bf3c819d76618418cdfbb7a749eb"
other = "H.264 libx264"
[encoder_libx265]
hash = "sha1-55544c166b1e15fd71a58096518e528109599eea"
other = "H.265 libx265"
[encoder_libxvid]
hash = "sha1-d4bed46d6cdd2bfa8fd1689801164a83ab10c3f5"
other = "libxvidcore MPEG-4 part 2"
[encoder_mjpeg]
hash = "sha1-94ba63a322b493a04da65e566781fe1cf8bb0d50"
other = "MJPEG (Motion JPEG)"
[encoder_mp2]
hash = "sha1-a9154b7203349e5d6fbfd67d1ea97715f54b2065"
other = "MP2 (MPEG audio layer 2)"
[encoder_mp2fixed]
hash = "sha1-dd2ee670d8bc8a60a96a717ebd26f16b5748cf3f"
other = "MP2 fixed point (MPEG audio layer 2)"
[encoder_mpeg1video]
hash = "sha1-30043660719a3cb19dab5c33450665a8a9cc1c01"
other = "MPEG-1"
[encoder_mpeg2video]
hash = "sha1-ccb2dcd8510cfdc9d52e5258af1863e5f2c51e77"
other = "MPEG-2"
[encoder_mpeg4]
hash = "sha1-67fe42f18421b2f6c90fcdc579f9199bfca4b182"
other = "MPEG-4 part 2"
[encoder_msmpeg4]
hash = "sha1-313ee597e4f0d9bd63a2bc6ac1618f028aef76f4"
other = "MPEG-4 part 2 Microsoft variant version 3"
[encoder_msmpeg4v2]
hash = "sha1-adc442ce88f2717693b2da3010a1937d77ee522f"
other = "MPEG-4 part 2 Microsoft variant version 2"
[encoder_msvideo1]
hash = "sha1-00f43ac0dc162bca10e0d98d6b70c0c6a902f66f"
other = "Microsoft Video-1"
[encoder_png]
hash = "sha1-6715d4b82f5d9dfe3e53e30b402ffa1a6fbf30a5"
other = "PNG image"
[encoder_qtrle]
hash = "sha1-31bf155cffaf6842ebc54084e4337ca08fdd9848"
other = "QuickTime Animation (RLE) video"
[encoder_sgi]
hash = "sha1-f4510e237f7fc3c02caa728f9e500f4b069f9c11"
other = "SGI image"
[encoder_tiff]
hash = "sha1-ed09d78c38e0b17ed695f35740c756dd7340eeac"
other = "TIFF image"
[encoder_wmav1]
hash = "sha1-cd4a4c5eeac694b6699d55d0f9b477b3b50f18c7"
other = "Windows Media Audio 1"
[encoder_wmav2]
hash = "sha1-eb2e5306cb33a702577ecfbdca0461862c66c053"
other = "Windows Media Audio 2"
[encoder_wmv1]
hash = "sha1-f9b748554c590c36a56bcba2cd317196b7bdeddb"
other = "Windows Media Video 7"
[encoder_wmv2]
hash = "sha1-5b21c87f5c6104797ead60b488b2948428f6b1b7"
other = "Windows Media Video 8"
[encoder_xbm]
hash = "sha1-2dfc35881da62e9a1379d8238cf7839b24f79566"
other = "XBM (X BitMap) image"
[error]
hash = "sha1-a7df8f8b5d754f226ac4cb320577fe692b33e483"
other = "An error has occurred!"
[errorConverter]
hash = "sha1-55ebddceddb8b044e33cc3893ec2eba7bbd9fcf9"
other = "Couldn't convert video"
[errorDatabase]
hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
other = "could not create file 'database' in folder 'data'"
[errorDatabaseTimeout]
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
other = "Could not open configuration file.\nMake sure another copy of the program is not running!"
[errorDragAndDropFile]
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
other = "Not all files were added"
[errorFFmpeg]
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
other = "this is not FFmpeg"
[errorFFmpegVersion]
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
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]
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
other = "this is not FFprobe"
[errorFFprobeVersion]
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
other = "Failed to determine FFprobe version"
[errorNoFilesAddedForConversion]
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
other = "There are no files to convert"
[errorQueue]
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
other = "Error"
[errorSelectedEncoder]
hash = "sha1-33ed1aaf4cb3c2ee9d8f8c325b9b75d16ddf9979"
other = "Converter not selected"
[errorSelectedFolderSave]
hash = "sha1-16f3ef93ee36813fdd79d8fb9bb7fc02acbb94a8"
other = "No save folder selected!"
[errorSelectedFormat]
hash = "sha1-cda92c56a1ef1aabc92bbfc405ede8ab13087e66"
other = "File extension not selected"
[exit]
hash = "sha1-c42457057d1ab7950cea00719cbe0b078891775f"
other = "Exit"
[ffmpegLGPL]
hash = "sha1-d395b16cc8f8eab98a8a970307c5b010ba22dde6"
other = "This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."
[ffmpegTrademark]
hash = "sha1-45f772b2eca5098cd6d31f2d1dc6edec1987a617"
other = "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."
[fileForConversionTitle]
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
other = "File:"
[fileQueueTitle]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Queue"
[formPreset]
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
other = "Preset"
[gratitude]
hash = "sha1-51968fc38e53a9a11c861126c62404674fd6096f"
other = "Gratitude"
[gratitudeText]
hash = "sha1-cb343e4d39ca31e6da6f72b9394cc915cb7d1258"
other = "I sincerely thank you for your invaluable\n\r and timely assistance:"
[help]
hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
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]
hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
other = "In Progress"
[languageSelectionFormHead]
hash = "sha1-0ff5fa82cf684112660128cba1711297acf11003"
other = "Switch language"
[languageSelectionHead]
hash = "sha1-daf1108fc10d3b1a908288d611f749b3cc651e4b"
other = "Choose language"
[licenseLink]
hash = "sha1-ea18ab849f0eea030d770da82c2a6b3484a7bd13"
other = "License information"
[licenseLinkOther]
hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
other = "Licenses from other products used in the program"
[menuSettingsLanguage]
hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
other = "Language"
[menuSettingsTheme]
hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
other = "Theme"
[or]
hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
other = "or"
[parameterCheckbox]
hash = "sha1-9e35221d454870996fd51d576249cf47d1784a3c"
other = "Enable option"
[pathToFfmpeg]
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
other = "Path to FFmpeg:"
[pathToFfplay]
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
other = "Path to FFplay:"
[pathToFfprobe]
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
other = "Path to FFprobe:"
[preset_fast]
hash = "sha1-935e1ac9d3c8ba4478326c909ba66662acb0540e"
other = "fast (slower than \"faster\", but the file will weigh less)"
[preset_faster]
hash = "sha1-98620b73c896440c39ea6ec4b9b19d41301c9a7e"
other = "faster (slower than \"veryfast\", but the file will weigh less)"
[preset_medium]
hash = "sha1-f7d1c30135c22c2f07c247075c0df103bb3c3ea5"
other = "medium (slower than \"fast\", but the file will weigh less)"
[preset_placebo]
hash = "sha1-7bcff099104bb192881139e6404981bd426b3f91"
other = "placebo (not recommended)"
[preset_slow]
hash = "sha1-681bf587275a45b48af49bb2ad8f0947919530e7"
other = "slow (slower than \"medium\", but the file will weigh less)"
[preset_slower]
hash = "sha1-d1c692ee2b7643ae2c71a48bea880327a3c6b1e3"
other = "slower (slower than \"slow\", but the file will weigh less)"
[preset_superfast]
hash = "sha1-41c39959e8f1547cc9259a5b459c4ccbf368cc23"
other = "superfast (slower than \"ultrafast\", but the file will weigh less)"
[preset_ultrafast]
hash = "sha1-dfed981573ac2046832f9a9450bc9388958753fa"
other = "ultrafast (fast, but the file will weigh a lot)"
[preset_veryfast]
hash = "sha1-370b82509887d02d7a2ef9b110df4616b16123ce"
other = "veryfast (slower than \"superfast\", but the file will weigh less)"
[preset_veryslow]
hash = "sha1-d428bfa6deea9dd5c7c1f80ceba24e123ae96d0d"
other = "veryslow (slower than \"slower\", but the file will weigh less)"
[programmLink]
hash = "sha1-18f9a3fad6aacefe1b05eed23122800b391ff5ca"
other = "Project website"
[programmVersion]
hash = "sha1-fa2e4994a301bb24bc2a8fa166e5486ea95a7475"
other = "**Program version:** {{.Version}}"
[queue]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Queue"
[save]
hash = "sha1-4864057d626a868fa60f999bed3191d61d045ddc"
other = "Save"
[selectEncoder]
hash = "sha1-88f3670b09758a3336057520a215058d61006abd"
other = "Encoder:"
[selectFFPathTitle]
hash = "sha1-95581446a28d968ff1a027c623159a7eb08654cf"
other = "Specify the path to FFmpeg and FFprobe"
[selectFormat]
hash = "sha1-f3809b0b48886570cd4cf1d7099de6da5b6d4524"
other = "File extension:"
[settings]
hash = "sha1-7f17c7c62a7fd8d1a508481f4778688927734c2f"
other = "Settings"
[testFF]
hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
other = "Checking FFmpeg for serviceability..."
[themesNameDark]
hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
other = "Dark"
[themesNameDefault]
hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
other = "Default"
[themesNameLight]
hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
other = "Light"
[titleDownloadLink]
hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
other = "You can download it from here"
[total]
hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94"
other = "Total"
[unzipRun]
hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36"
other = "Unpacked..."
[waitingQueue]
hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2"
other = "Waiting"

571
languages/active.kk.toml Normal file
View File

@@ -0,0 +1,571 @@
[AlsoUsedProgram]
hash = "sha1-a72be72e7808bb8a0144ed7a93acb29c568b1ed4"
other = "Бағдарлама сонымен қатар пайдаланады:"
[about]
hash = "sha1-3da0b9ef719fd707f443ac00404447f29445976f"
other = "Бағдарлама туралы"
[aboutText]
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін."
[addedFilesTitle]
hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
other = "Қосылған файлдар"
[autoClearAfterAddingToQueue]
hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
other = "Кезекке қосқаннан кейін тазалаңыз"
[buttonDownloadFFmpeg]
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
other = "FFmpeg автоматты түрде жүктеп алыңыз"
[buttonForSelectedDirTitle]
hash = "sha1-8cbe5c67bcf89e4624635a79cbea104227faedda"
other = "Қалтаға сақтаңыз:"
[cancel]
hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
other = "Болдырмау"
[changeFFPath]
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
other = "FFmpeg, FFprobe және FFplay"
[changeLanguage]
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
other = "Тілді өзгерту"
[checkboxOverwriteOutputFilesTitle]
hash = "sha1-5860124bb781e7ef680f573fa93977e96328d4e7"
other = "Файлды қайта жазуға рұқсат беріңіз"
[choose]
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
other = "таңдау"
[clearAll]
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
other = "Тізімді өшіру"
[completedQueue]
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
other = "Дайын"
[converterVideoFilesSubmitTitle]
hash = "sha1-7ac460f3c24c9952082f2db6e4d62f752598709c"
other = "Файлды түрлендіру"
[converterVideoFilesTitle]
hash = "sha1-1ab29597cc9dfefab08e54ea5442e7ffa15f0394"
other = "Бейне, аудио және суретті түрлендіргіш"
[download]
hash = "sha1-fe8f79f29da457de2f6bc9531de6e536e0c426ad"
other = "Жүктеп алу"
[downloadFFmpegFromSite]
hash = "sha1-0889c95aa3a8659d8d903b4dab7097699c4d8aa4"
other = "Сайттан жүктеледі:"
[downloadRun]
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
other = "Жүктеп алынуда..."
[dragAndDropFiles]
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
other = "файлдарды сүйреп апарыңыз"
[encoderGroupAudio]
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
other = "Аудио"
[encoderGroupImage]
hash = "sha1-a7e528bc7ac9538aec87d1593c38b80be95d4745"
other = "Суреттер"
[encoderGroupVideo]
hash = "sha1-8e7b9894c7ef0f57ac0bf910f6a8aac1c8a53683"
other = "Бейне"
[encoder_apng]
hash = "sha1-1cbd9abfef96d5614a7e569161b41bd6ad87bbaf"
other = "APNG image"
[encoder_bmp]
hash = "sha1-e0b9c16b016961a5abdc2217e8ffd1ba7ddebc40"
other = "BMP image"
[encoder_flv]
hash = "sha1-3602bbf1cc90e48254f81975c7879b5fc0c4d602"
other = "FLV"
[encoder_gif]
hash = "sha1-d092a779172291b5215aa095390a5b11659128a4"
other = "GIF image"
[encoder_h264_nvenc]
hash = "sha1-169389f8c4a2518410159c363378ab5c978c32e5"
other = "NVIDIA қолдауымен H.264"
[encoder_libmp3lame]
hash = "sha1-cd2c8d6f246c8bc18554b7105cb50b78d3cb2b98"
other = "libmp3lame MP3 (MPEG audio layer 3)"
[encoder_libshine]
hash = "sha1-891d56c85857e5d83ef5a1fe077c1f1540788f49"
other = "libshine MP3 (MPEG audio layer 3)"
[encoder_libtwolame]
hash = "sha1-b2f53be810b74edc3c454ac75de7ddecfee322ca"
other = "libtwolame MP2 (MPEG audio layer 2)"
[encoder_libvpx]
hash = "sha1-b85c923aecfb48de0e87e71b6a21bfc2c547c70e"
other = "libvpx VP8 (codec vp8)"
[encoder_libvpx-vp9]
hash = "sha1-3106417bd89bee87daa691e87614caf78cb934fe"
other = "libvpx VP9 (codec vp9)"
[encoder_libwebp]
hash = "sha1-1d590d47d46f7880246061fce0e0de6d743db39e"
other = "libwebp WebP image"
[encoder_libwebp_anim]
hash = "sha1-f141a9c8f23d79c13d44c30d8f34e05b363771ad"
other = "libwebp_anim WebP image"
[encoder_libx264]
hash = "sha1-6d764ac459c0bf3c819d76618418cdfbb7a749eb"
other = "H.264 libx264"
[encoder_libx265]
hash = "sha1-55544c166b1e15fd71a58096518e528109599eea"
other = "H.265 libx265"
[encoder_libxvid]
hash = "sha1-d4bed46d6cdd2bfa8fd1689801164a83ab10c3f5"
other = "libxvidcore MPEG-4 part 2"
[encoder_mjpeg]
hash = "sha1-94ba63a322b493a04da65e566781fe1cf8bb0d50"
other = "MJPEG (Motion JPEG)"
[encoder_mp2]
hash = "sha1-a9154b7203349e5d6fbfd67d1ea97715f54b2065"
other = "MP2 (MPEG audio layer 2)"
[encoder_mp2fixed]
hash = "sha1-dd2ee670d8bc8a60a96a717ebd26f16b5748cf3f"
other = "MP2 fixed point (MPEG audio layer 2)"
[encoder_mpeg1video]
hash = "sha1-30043660719a3cb19dab5c33450665a8a9cc1c01"
other = "MPEG-1"
[encoder_mpeg2video]
hash = "sha1-ccb2dcd8510cfdc9d52e5258af1863e5f2c51e77"
other = "MPEG-2"
[encoder_mpeg4]
hash = "sha1-67fe42f18421b2f6c90fcdc579f9199bfca4b182"
other = "MPEG-4 part 2"
[encoder_msmpeg4]
hash = "sha1-313ee597e4f0d9bd63a2bc6ac1618f028aef76f4"
other = "MPEG-4 part 2 Microsoft variant version 3"
[encoder_msmpeg4v2]
hash = "sha1-adc442ce88f2717693b2da3010a1937d77ee522f"
other = "MPEG-4 part 2 Microsoft variant version 2"
[encoder_msvideo1]
hash = "sha1-00f43ac0dc162bca10e0d98d6b70c0c6a902f66f"
other = "Microsoft Video-1"
[encoder_png]
hash = "sha1-6715d4b82f5d9dfe3e53e30b402ffa1a6fbf30a5"
other = "PNG image"
[encoder_qtrle]
hash = "sha1-31bf155cffaf6842ebc54084e4337ca08fdd9848"
other = "QuickTime Animation (RLE) video"
[encoder_sgi]
hash = "sha1-f4510e237f7fc3c02caa728f9e500f4b069f9c11"
other = "SGI image"
[encoder_tiff]
hash = "sha1-ed09d78c38e0b17ed695f35740c756dd7340eeac"
other = "TIFF image"
[encoder_wmav1]
hash = "sha1-cd4a4c5eeac694b6699d55d0f9b477b3b50f18c7"
other = "Windows Media Audio 1"
[encoder_wmav2]
hash = "sha1-eb2e5306cb33a702577ecfbdca0461862c66c053"
other = "Windows Media Audio 2"
[encoder_wmv1]
hash = "sha1-f9b748554c590c36a56bcba2cd317196b7bdeddb"
other = "Windows Media Video 7"
[encoder_wmv2]
hash = "sha1-5b21c87f5c6104797ead60b488b2948428f6b1b7"
other = "Windows Media Video 8"
[encoder_xbm]
hash = "sha1-2dfc35881da62e9a1379d8238cf7839b24f79566"
other = "XBM (X BitMap) image"
[error]
hash = "sha1-a7df8f8b5d754f226ac4cb320577fe692b33e483"
other = "Қате орын алды!"
[errorConverter]
hash = "sha1-55ebddceddb8b044e33cc3893ec2eba7bbd9fcf9"
other = "Бейнені түрлендіру мүмкін болмады"
[errorDatabase]
hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
other = "'data' қалтасында 'database' файлын жасау мүмкін болмады"
[errorDatabaseTimeout]
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
other = "Конфигурация файлын аша алмады.\nБағдарламаның басқа көшірмесі іске қосылмағанына көз жеткізіңіз!"
[errorDragAndDropFile]
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
other = "Барлық файлдар қосылмаған"
[errorFFmpeg]
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
other = "бұл FFmpeg емес"
[errorFFmpegVersion]
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
other = "FFmpeg нұсқасын анықтау мүмкін болмады"
[errorFFplay]
hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
other = "бұл FFplay емес"
[errorFFplayVersion]
hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
other = "FFplay нұсқасын анықтау мүмкін болмады"
[errorFFprobe]
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
other = "бұл FFprobe емес"
[errorFFprobeVersion]
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
other = "FFprobe нұсқасын анықтау мүмкін болмады"
[errorNoFilesAddedForConversion]
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
other = "Түрлендіруге арналған файлдар жоқ"
[errorQueue]
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
other = "Қате"
[errorSelectedEncoder]
hash = "sha1-33ed1aaf4cb3c2ee9d8f8c325b9b75d16ddf9979"
other = "Түрлендіргіш таңдалмаған"
[errorSelectedFolderSave]
hash = "sha1-16f3ef93ee36813fdd79d8fb9bb7fc02acbb94a8"
other = "Сақтау қалтасы таңдалмаған!"
[errorSelectedFormat]
hash = "sha1-cda92c56a1ef1aabc92bbfc405ede8ab13087e66"
other = "Файл кеңейтімі таңдалмаған"
[exit]
hash = "sha1-c42457057d1ab7950cea00719cbe0b078891775f"
other = "Шығу"
[ffmpegLGPL]
hash = "sha1-d395b16cc8f8eab98a8a970307c5b010ba22dde6"
other = "Бұл бағдарламалық құрал **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)** астында **FFmpeg** жобасының кітапханаларын пайдаланады."
[ffmpegTrademark]
hash = "sha1-45f772b2eca5098cd6d31f2d1dc6edec1987a617"
other = "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын жасаушы **[Fabrice Bellard](http://bellard.org/)** сауда белгісі."
[fileForConversionTitle]
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
other = "Файл:"
[fileQueueTitle]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Кезек"
[formPreset]
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
other = "Алдын ала орнатылған"
[gratitude]
hash = "sha1-51968fc38e53a9a11c861126c62404674fd6096f"
other = "Алғыс"
[gratitudeText]
hash = "sha1-cb343e4d39ca31e6da6f72b9394cc915cb7d1258"
other = "Сізге баға жетпес және уақтылы көмектескеніңіз\n\r үшін шын жүректен алғыс айтамын:"
[help]
hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
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]
hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
other = "Орындалуда"
[languageSelectionFormHead]
hash = "sha1-0ff5fa82cf684112660128cba1711297acf11003"
other = "Тілді ауыстыру"
[languageSelectionHead]
hash = "sha1-daf1108fc10d3b1a908288d611f749b3cc651e4b"
other = "Тілді таңдаңыз"
[licenseLink]
hash = "sha1-ea18ab849f0eea030d770da82c2a6b3484a7bd13"
other = "Лицензия туралы ақпарат"
[licenseLinkOther]
hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
other = "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары"
[menuSettingsLanguage]
hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
other = "Тіл"
[menuSettingsTheme]
hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
other = "Тақырып"
[or]
hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
other = "немесе"
[parameterCheckbox]
hash = "sha1-9e35221d454870996fd51d576249cf47d1784a3c"
other = "Опцияны қосу"
[pathToFfmpeg]
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
other = "FFmpeg жол:"
[pathToFfplay]
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
other = "FFplay жол:"
[pathToFfprobe]
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
other = "FFprobe жол:"
[preset_fast]
hash = "sha1-935e1ac9d3c8ba4478326c909ba66662acb0540e"
other = "fast («faster» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_faster]
hash = "sha1-98620b73c896440c39ea6ec4b9b19d41301c9a7e"
other = "faster («veryfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_medium]
hash = "sha1-f7d1c30135c22c2f07c247075c0df103bb3c3ea5"
other = "medium («fast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_placebo]
hash = "sha1-7bcff099104bb192881139e6404981bd426b3f91"
other = "placebo (ұсынылмайды)"
[preset_slow]
hash = "sha1-681bf587275a45b48af49bb2ad8f0947919530e7"
other = "slow («medium» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_slower]
hash = "sha1-d1c692ee2b7643ae2c71a48bea880327a3c6b1e3"
other = "slower («slow» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_superfast]
hash = "sha1-41c39959e8f1547cc9259a5b459c4ccbf368cc23"
other = "superfast («ultrafast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_ultrafast]
hash = "sha1-dfed981573ac2046832f9a9450bc9388958753fa"
other = "ultrafast (жылдам, бірақ файлдың салмағы көп болады)"
[preset_veryfast]
hash = "sha1-370b82509887d02d7a2ef9b110df4616b16123ce"
other = "veryfast («superfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[preset_veryslow]
hash = "sha1-d428bfa6deea9dd5c7c1f80ceba24e123ae96d0d"
other = "veryslow («slower» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
[programmLink]
hash = "sha1-18f9a3fad6aacefe1b05eed23122800b391ff5ca"
other = "Жобаның веб-сайты"
[programmVersion]
hash = "sha1-fa2e4994a301bb24bc2a8fa166e5486ea95a7475"
other = "**Бағдарлама нұсқасы:** {{.Version}}"
[queue]
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
other = "Кезек"
[save]
hash = "sha1-4864057d626a868fa60f999bed3191d61d045ddc"
other = "Сақтау"
[selectEncoder]
hash = "sha1-88f3670b09758a3336057520a215058d61006abd"
other = "Кодировщик:"
[selectFFPathTitle]
hash = "sha1-95581446a28d968ff1a027c623159a7eb08654cf"
other = "FFmpeg және FFprobe жолын көрсетіңіз"
[selectFormat]
hash = "sha1-f3809b0b48886570cd4cf1d7099de6da5b6d4524"
other = "Файл кеңейтімі:"
[settings]
hash = "sha1-7f17c7c62a7fd8d1a508481f4778688927734c2f"
other = "Параметрлер"
[testFF]
hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
other = "FFmpeg функционалдығы тексерілуде..."
[themesNameDark]
hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
other = "Қараңғы тақырып"
[themesNameDefault]
hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
other = "Әдепкі бойынша"
[themesNameLight]
hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
other = "Жеңіл тақырып"
[titleDownloadLink]
hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
other = "Сіз оны осы жерден жүктей аласыз"
[total]
hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94"
other = "Барлығы"
[unzipRun]
hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36"
other = "Орамнан шығарылуда..."
[waitingQueue]
hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2"
other = "Күту"

143
languages/active.ru.toml Normal file
View File

@@ -0,0 +1,143 @@
AlsoUsedProgram = "Также в программе используется:"
about = "О программе"
aboutText = "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg."
addedFilesTitle = "Добавленные файлы"
autoClearAfterAddingToQueue = "Очищать после добавления в очередь"
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
buttonForSelectedDirTitle = "Сохранить в папку:"
cancel = "Отмена"
changeFFPath = "FFmpeg, FFprobe и FFplay"
changeLanguage = "Поменять язык"
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
choose = "выбрать"
clearAll = "Очистить список"
completedQueue = "Готово"
converterVideoFilesSubmitTitle = "Конвертировать"
converterVideoFilesTitle = "Конвертер видео, аудио и картинок"
download = "Скачать"
downloadFFmpegFromSite = "Будет скачано с сайта:"
downloadRun = "Скачивается..."
dragAndDropFiles = "перетащить файлы"
encoderGroupAudio = "Аудио"
encoderGroupImage = "Картинки"
encoderGroupVideo = "Видео"
encoder_apng = "APNG image"
encoder_bmp = "BMP image"
encoder_flv = "FLV"
encoder_gif = "GIF image"
encoder_h264_nvenc = "H.264 с поддержкой NVIDIA"
encoder_libmp3lame = "libmp3lame MP3 (MPEG audio layer 3)"
encoder_libshine = "libshine MP3 (MPEG audio layer 3)"
encoder_libtwolame = "libtwolame MP2 (MPEG audio layer 2)"
encoder_libvpx = "libvpx VP8 (codec vp8)"
encoder_libvpx-vp9 = "libvpx VP9 (codec vp9)"
encoder_libwebp = "libwebp WebP image"
encoder_libwebp_anim = "libwebp_anim WebP image"
encoder_libx264 = "H.264 libx264"
encoder_libx265 = "H.265 libx265"
encoder_libxvid = "libxvidcore MPEG-4 part 2"
encoder_mjpeg = "MJPEG (Motion JPEG)"
encoder_mp2 = "MP2 (MPEG audio layer 2)"
encoder_mp2fixed = "MP2 fixed point (MPEG audio layer 2)"
encoder_mpeg1video = "MPEG-1"
encoder_mpeg2video = "MPEG-2"
encoder_mpeg4 = "MPEG-4 part 2"
encoder_msmpeg4 = "MPEG-4 part 2 Microsoft variant version 3"
encoder_msmpeg4v2 = "MPEG-4 part 2 Microsoft variant version 2"
encoder_msvideo1 = "Microsoft Video-1"
encoder_png = "PNG image"
encoder_qtrle = "QuickTime Animation (RLE) video"
encoder_sgi = "SGI image"
encoder_tiff = "TIFF image"
encoder_wmav1 = "Windows Media Audio 1"
encoder_wmav2 = "Windows Media Audio 2"
encoder_wmv1 = "Windows Media Video 7"
encoder_wmv2 = "Windows Media Video 8"
encoder_xbm = "XBM (X BitMap) image"
error = "Произошла ошибка!"
errorConverter = "не смогли отконвертировать видео"
errorDatabase = "не смогли создать файл 'database' в папке 'data'"
errorDatabaseTimeout = "Не смогли открыть файл конфигурации.\nУбедитесь, что другая копия программы не запущена!"
errorDragAndDropFile = "Не все файлы добавились"
errorFFmpeg = "это не FFmpeg"
errorFFmpegVersion = "Не смогли определить версию FFmpeg"
errorFFplay = "это не FFplay"
errorFFplayVersion = "Не смогли определить версию FFplay"
errorFFprobe = "это не FFprobe"
errorFFprobeVersion = "Не смогли определить версию FFprobe"
errorNoFilesAddedForConversion = "Нет файлов для конвертации"
errorQueue = "Ошибка"
errorSelectedEncoder = "Конвертер не выбран"
errorSelectedFolderSave = "Папка для сохранения не выбрана!"
errorSelectedFormat = "Расширение файла не выбрана"
exit = "Выход"
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)**."
fileForConversionTitle = "Файл:"
fileQueueTitle = "Очередь"
formPreset = "Предустановка"
gratitude = "Благодарность"
gratitudeText = "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:"
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 = "Выполняется"
languageSelectionFormHead = "Переключить язык"
languageSelectionHead = "Выберите язык"
licenseLink = "Сведения о лицензии"
licenseLinkOther = "Лицензии от других продуктов, которые используются в программе"
menuSettingsLanguage = "Язык"
menuSettingsTheme = "Тема"
or = "или"
parameterCheckbox = "Включить параметр"
pathToFfmpeg = "Путь к FFmpeg:"
pathToFfplay = "Путь к FFplay:"
pathToFfprobe = "Путь к FFprobe:"
preset_fast = "fast (медленней чем faster, но будет файл и меньше весить)"
preset_faster = "faster (медленней чем veryfast, но будет файл и меньше весить)"
preset_medium = "medium (медленней чем fast, но будет файл и меньше весить)"
preset_placebo = "placebo (не рекомендуется)"
preset_slow = "slow (медленней чем medium, но будет файл и меньше весить)"
preset_slower = "slower (медленней чем slow, но будет файл и меньше весить)"
preset_superfast = "superfast (медленней чем ultrafast, но будет файл и меньше весить)"
preset_ultrafast = "ultrafast (быстро, но файл будет много весить)"
preset_veryfast = "veryfast (медленней чем superfast, но будет файл и меньше весить)"
preset_veryslow = "veryslow (медленней чем slower, но будет файл и меньше весить)"
programmLink = "Сайт проекта"
programmVersion = "**Версия программы:** {{.Version}}"
queue = "Очередь"
save = "Сохранить"
selectEncoder = "Кодировщик:"
selectFFPathTitle = "Укажите путь к FFmpeg и к FFprobe"
selectFormat = "Расширение файла:"
settings = "Настройки"
testFF = "Проверка FFmpeg на работоспособность..."
themesNameDark = "Тёмная"
themesNameDefault = "По умолчанию"
themesNameLight = "Светлая"
titleDownloadLink = "Скачать можно от сюда"
total = "Всего"
unzipRun = "Распаковывается..."
waitingQueue = "В очереди"

26
localizer/repository.go Normal file
View File

@@ -0,0 +1,26 @@
package localizer
import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
)
type RepositoryContract interface {
GetCode() (string, error)
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, error) {
return r.settingRepository.GetValue("language")
}
func (r Repository) Save(code string) (setting.Setting, error) {
return r.settingRepository.CreateOrUpdate("language", code)
}

View File

@@ -4,6 +4,7 @@ import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"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"
) )
type ViewContract interface { type ViewContract interface {
@@ -34,11 +35,13 @@ func (v View) LanguageSelection(funcSelected func(lang kernel.Lang)) {
block.SetText(languages[i].Title) block.SetText(languages[i].Title)
}) })
listView.OnSelected = func(id widget.ListItemID) { listView.OnSelected = func(id widget.ListItemID) {
_ = v.app.GetLocalizerService().SetCurrentLanguage(languages[id], true) _ = v.app.GetLocalizerService().SetCurrentLanguage(languages[id])
funcSelected(languages[id]) funcSelected(languages[id])
} }
messageHead := v.app.GetLocalizerService().GetMessage("languageSelectionHead") messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "languageSelectionHead",
})
v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", listView)) v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", listView))
} }
@@ -55,15 +58,17 @@ func LanguageSelectionForm(localizerService kernel.LocalizerContract, funcSelect
func(i widget.ListItemID, o fyne.CanvasObject) { func(i widget.ListItemID, o fyne.CanvasObject) {
block := o.(*widget.Label) block := o.(*widget.Label)
block.SetText(languages[i].Title) block.SetText(languages[i].Title)
if languages[i].Code == currentLanguage.Code { if languages[i].Code == currentLanguage.Lang.Code {
block.TextStyle = fyne.TextStyle{Bold: true} block.TextStyle = fyne.TextStyle{Bold: true}
} }
}) })
listView.OnSelected = func(id widget.ListItemID) { listView.OnSelected = func(id widget.ListItemID) {
_ = localizerService.SetCurrentLanguage(languages[id], true) _ = localizerService.SetCurrentLanguage(languages[id])
funcSelected(languages[id]) funcSelected(languages[id])
} }
messageHead := localizerService.GetMessage("languageSelectionFormHead") messageHead := localizerService.GetMessage(&i18n.LocalizeConfig{
MessageID: "languageSelectionFormHead",
})
return widget.NewCard(messageHead, "", listView) return widget.NewCard(messageHead, "", listView)
} }

82
main.go
View File

@@ -1,28 +1,40 @@
package main package main
import ( import (
_ "embed" "errors"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor"
dberror "git.kor-elf.net/kor-elf/gui-for-ffmpeg/db"
error2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/error" error2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/error"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/handler" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/handler"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/resources"
"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/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" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"go.etcd.io/bbolt"
"golang.org/x/text/language"
"os"
"time"
) )
var application kernel.AppContract var application kernel.AppContract
var ffPathUtilities *kernel.FFPathUtilities var ffPathUtilities *kernel.FFPathUtilities
func init() { func init() {
iconResource, _ := fyne.LoadResourceFromPath("icon.png")
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.9.0",
Icon: resources.IconAppLogoResource(), Icon: iconResource,
}
localizerService, err := kernel.NewLocalizer("languages", language.Russian)
if err != nil {
kernel.PanicErrorLang(err, appMetadata)
return
} }
ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""} ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""}
@@ -32,6 +44,7 @@ func init() {
queue := kernel.NewQueueList() queue := kernel.NewQueueList()
application = kernel.NewApp( application = kernel.NewApp(
appMetadata, appMetadata,
localizerService,
queue, queue,
ffplayService, ffplayService,
convertorService, convertorService,
@@ -40,14 +53,55 @@ func init() {
func main() { func main() {
errorView := error2.NewView(application) errorView := error2.NewView(application)
if canCreateFile("data/database.db") != true {
errorView.PanicErrorWriteDirectoryData()
application.GetWindow().ShowAndRun()
return
}
settingRepository := setting.NewRepository(application.GetAppFyne()) db, err := bbolt.Open("data/database.db", 0600, &bbolt.Options{Timeout: 3 * time.Second})
if err != nil {
errorView.PanicError(err)
application.GetWindow().ShowAndRun()
return
}
defer db.Close()
err = migration.Run(db)
if err != nil {
errorView.PanicError(err)
application.GetWindow().ShowAndRun()
return
}
settingRepository := setting.NewRepository(db)
settingDirectoryForSaving := setting.NewSettingDirectoryForSaving(settingRepository) settingDirectoryForSaving := setting.NewSettingDirectoryForSaving(settingRepository)
convertorRepository := convertor.NewRepository(settingRepository) convertorRepository := convertor.NewRepository(settingRepository)
ffPathUtilities.FFmpeg = convertorRepository.GetPathFfmpeg() pathFFmpeg, err := convertorRepository.GetPathFfmpeg()
ffPathUtilities.FFprobe = convertorRepository.GetPathFfprobe() if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
ffPathUtilities.FFplay = convertorRepository.GetPathFfplay() errorView.PanicError(err)
application.GetWindow().ShowAndRun()
return
}
ffPathUtilities.FFmpeg = pathFFmpeg
pathFFprobe, err := convertorRepository.GetPathFfprobe()
if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
errorView.PanicError(err)
application.GetWindow().ShowAndRun()
return
}
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()
@@ -64,13 +118,23 @@ func main() {
themeRepository := theme.NewRepository(settingRepository) themeRepository := theme.NewRepository(settingRepository)
themeService := theme.NewTheme(application, themeRepository) themeService := theme.NewTheme(application, themeRepository)
localizerRepository := localizer.NewRepository(settingRepository)
menuView := menu.NewView(application) menuView := menu.NewView(application)
menuSettingView := menu.NewViewSetting(application, themeService) menuSettingView := menu.NewViewSetting(application, themeService)
mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, menuSettingView, localizerView, themeService) mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, menuSettingView, localizerView, localizerRepository, themeService)
mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu) mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu, localizerRepository)
mainHandler.Start() mainHandler.Start()
application.GetWindow().SetMainMenu(mainMenu.GetMainMenu()) application.GetWindow().SetMainMenu(mainMenu.GetMainMenu())
application.GetWindow().ShowAndRun() application.GetWindow().ShowAndRun()
} }
func canCreateFile(path string) bool {
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
return false
}
_ = file.Close()
return true
}

View File

@@ -6,8 +6,8 @@ import (
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/resources"
"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"
"golang.org/x/image/colornames" "golang.org/x/image/colornames"
"net/url" "net/url"
) )
@@ -29,15 +29,19 @@ func NewView(app kernel.AppContract) *View {
} }
func (v View) Gratitude() { func (v View) Gratitude() {
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage("gratitude")) view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "gratitude",
}))
view.Resize(fyne.Size{Width: 500, Height: 400}) view.Resize(fyne.Size{Width: 500, Height: 400})
view.SetFixedSize(true) view.SetFixedSize(true)
image := canvas.NewImageFromResource(resources.IconAppLogoResource()) image := canvas.NewImageFromFile("icon.png")
image.SetMinSize(fyne.Size{Width: 100, Height: 100}) image.SetMinSize(fyne.Size{Width: 100, Height: 100})
image.FillMode = canvas.ImageFillContain image.FillMode = canvas.ImageFillContain
gratitude := canvas.NewText(v.app.GetLocalizerService().GetMessage("gratitude"), colornames.Darkgreen) gratitude := canvas.NewText(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "gratitude",
}), colornames.Darkgreen)
gratitude.TextStyle = fyne.TextStyle{Bold: true} gratitude.TextStyle = fyne.TextStyle{Bold: true}
gratitude.TextSize = 20 gratitude.TextSize = 20
@@ -45,11 +49,13 @@ func (v View) Gratitude() {
container.NewScroll(container.NewVBox( container.NewScroll(container.NewVBox(
container.NewBorder(nil, nil, container.NewVBox(image), nil, container.NewVBox( container.NewBorder(nil, nil, container.NewVBox(image), nil, container.NewVBox(
gratitude, gratitude,
widget.NewLabel(v.app.GetLocalizerService().GetMessage("gratitudeText")), widget.NewLabel(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "gratitudeText",
})),
widget.NewLabel("Екатерина"), widget.NewLabel("Екатерина"),
widget.NewLabel("Евгений"), widget.NewLabel("Евгений"),
)), ),
)), ))),
) )
view.CenterOnScreen() view.CenterOnScreen()
@@ -57,7 +63,9 @@ func (v View) Gratitude() {
} }
func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) { func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) {
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage("about")) view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "about",
}))
view.Resize(fyne.Size{Width: 793, Height: 550}) view.Resize(fyne.Size{Width: 793, Height: 550})
view.SetFixedSize(true) view.SetFixedSize(true)
@@ -65,51 +73,54 @@ func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion s
programmName.TextStyle = fyne.TextStyle{Bold: true} programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20 programmName.TextSize = 20
programmLink := widget.NewHyperlink( programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("programmLink"), MessageID: "programmLink",
&url.URL{ }), &url.URL{
Scheme: "https", Scheme: "https",
Host: "gui-for-ffmpeg.projects.kor-elf.net", Host: "gui-for-ffmpeg.projects.kor-elf.net",
Path: "/", Path: "/",
}, })
)
licenseLink := widget.NewHyperlink( licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("licenseLink"), MessageID: "licenseLink",
&url.URL{ }), &url.URL{
Scheme: "https", Scheme: "https",
Host: "git.kor-elf.net", Host: "git.kor-elf.net",
Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE", Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE",
}, })
)
licenseLinkOther := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage( licenseLinkOther := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
"licenseLinkOther"), MessageID: "licenseLinkOther",
&url.URL{ }), &url.URL{
Scheme: "https", Scheme: "https",
Host: "git.kor-elf.net", Host: "git.kor-elf.net",
Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE-3RD-PARTY.txt", Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE-3RD-PARTY.txt",
}, })
)
programmVersion := widget.NewRichTextFromMarkdown( programmVersion := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage( MessageID: "programmVersion",
"programmVersion", TemplateData: map[string]string{
map[string]any{"Version": v.app.GetAppFyne().Metadata().Version}, "Version": v.app.GetAppFyne().Metadata().Version,
), },
) }))
aboutText := widget.NewRichText( aboutText := widget.NewRichText(
&widget.TextSegment{ &widget.TextSegment{
Text: v.app.GetLocalizerService().GetMessage("aboutText"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "aboutText",
}),
}, },
) )
image := canvas.NewImageFromResource(resources.IconAppLogoResource()) image := canvas.NewImageFromFile("icon.png")
image.SetMinSize(fyne.Size{Width: 100, Height: 100}) image.SetMinSize(fyne.Size{Width: 100, Height: 100})
image.FillMode = canvas.ImageFillContain image.FillMode = canvas.ImageFillContain
ffmpegTrademark := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage("ffmpegTrademark")) ffmpegTrademark := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
ffmpegLGPL := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage("ffmpegLGPL")) MessageID: "ffmpegTrademark",
}))
ffmpegLGPL := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "ffmpegLGPL",
}))
view.SetContent( view.SetContent(
container.NewScroll(container.NewVBox( container.NewScroll(container.NewVBox(
@@ -126,7 +137,9 @@ 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), v.getAboutFfplay(ffplayVersion),
widget.NewCard(v.app.GetLocalizerService().GetMessage("AlsoUsedProgram"), "", v.getOther()), widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "AlsoUsedProgram",
}), "", v.getOther()),
)), )),
) )
view.CenterOnScreen() view.CenterOnScreen()
@@ -134,71 +147,119 @@ func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion s
} }
func (v View) HelpFFplay() { func (v View) HelpFFplay() {
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage("helpFFplay")) view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplay",
}))
view.Resize(fyne.Size{Width: 800, Height: 550}) view.Resize(fyne.Size{Width: 800, Height: 550})
view.SetFixedSize(true) view.SetFixedSize(true)
data := [][]string{ data := [][]string{
[]string{ []string{
v.app.GetLocalizerService().GetMessage("helpFFplayKeys"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplayDescription"), MessageID: "helpFFplayKeys",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayDescription",
}),
}, },
[]string{ []string{
"Q, ESC", "Q, ESC",
v.app.GetLocalizerService().GetMessage("helpFFplayQuit"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayQuit",
}),
}, },
[]string{ []string{
"F, " + v.app.GetLocalizerService().GetMessage("helpFFplayDoubleClickLeftMouseButton"), "F, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplayToggleFullScreen"), MessageID: "helpFFplayDoubleClickLeftMouseButton",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayToggleFullScreen",
}),
}, },
[]string{ []string{
"P, " + "P, " +
v.app.GetLocalizerService().GetMessage("helpFFplayKeySpace"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplayPause"), MessageID: "helpFFplayKeySpace",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayPause",
}),
}, },
[]string{ []string{
"M", "M",
v.app.GetLocalizerService().GetMessage("helpFFplayToggleMute"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayToggleMute",
}),
}, },
[]string{ []string{
"9, /", "9, /",
v.app.GetLocalizerService().GetMessage("helpFFplayDecreaseVolume"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayDecreaseVolume",
}),
}, },
[]string{ []string{
"0, *", "0, *",
v.app.GetLocalizerService().GetMessage("helpFFplayIncreaseVolume"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayIncreaseVolume",
}),
}, },
[]string{ []string{
v.app.GetLocalizerService().GetMessage("helpFFplayKeyLeft"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplaySeekBackward10Seconds"), MessageID: "helpFFplayKeyLeft",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward10Seconds",
}),
}, },
[]string{ []string{
v.app.GetLocalizerService().GetMessage("helpFFplayKeyRight"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplaySeekForward10Seconds"), MessageID: "helpFFplayKeyRight",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekForward10Seconds",
}),
}, },
[]string{ []string{
v.app.GetLocalizerService().GetMessage("helpFFplayKeyDown"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplaySeekBackward1Minute"), MessageID: "helpFFplayKeyDown",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward1Minute",
}),
}, },
[]string{ []string{
v.app.GetLocalizerService().GetMessage("helpFFplayKeyUp"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplaySeekBForward1Minute"), MessageID: "helpFFplayKeyUp",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBForward1Minute",
}),
}, },
[]string{ []string{
"Page Down", "Page Down",
v.app.GetLocalizerService().GetMessage("helpFFplaySeekBackward10Minutes"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBackward10Minutes",
}),
}, },
[]string{ []string{
"Page Up", "Page Up",
v.app.GetLocalizerService().GetMessage("helpFFplaySeekBForward10Minutes"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplaySeekBForward10Minutes",
}),
}, },
[]string{ []string{
"S, " + v.app.GetLocalizerService().GetMessage("helpFFplayKeyHoldS"), "S, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
v.app.GetLocalizerService().GetMessage("helpFFplayActivateFrameStepMode"), MessageID: "helpFFplayKeyHoldS",
}),
v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayActivateFrameStepMode",
}),
}, },
[]string{ []string{
"W", "W",
v.app.GetLocalizerService().GetMessage("helpFFplayCycleVideoFiltersOrShowModes"), v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "helpFFplayCycleVideoFiltersOrShowModes",
}),
}, },
} }
@@ -239,13 +300,17 @@ func (v View) getAboutFfmpeg(version string) *fyne.Container {
programmName.TextStyle = fyne.TextStyle{Bold: true} programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20 programmName.TextSize = 20
programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("programmLink"), &url.URL{ programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "programmLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "", Path: "",
}) })
licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("licenseLink"), &url.URL{ licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "licenseLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "legal.html", Path: "legal.html",
@@ -265,13 +330,17 @@ func (v View) getAboutFfprobe(version string) *fyne.Container {
programmName.TextStyle = fyne.TextStyle{Bold: true} programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20 programmName.TextSize = 20
programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("programmLink"), &url.URL{ programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "programmLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "ffprobe.html", Path: "ffprobe.html",
}) })
licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("licenseLink"), &url.URL{ licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "licenseLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "legal.html", Path: "legal.html",
@@ -291,13 +360,17 @@ func (v View) getAboutFfplay(version string) *fyne.Container {
programmName.TextStyle = fyne.TextStyle{Bold: true} programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20 programmName.TextSize = 20
programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("programmLink"), &url.URL{ programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "programmLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "ffplay.html", Path: "ffplay.html",
}) })
licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage("licenseLink"), &url.URL{ licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "licenseLink",
}), &url.URL{
Scheme: "https", Scheme: "https",
Host: "ffmpeg.org", Host: "ffmpeg.org",
Path: "legal.html", Path: "legal.html",

View File

@@ -6,6 +6,7 @@ import (
"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/theme" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
"github.com/nicksnyder/go-i18n/v2/i18n"
"image/color" "image/color"
) )
@@ -39,7 +40,7 @@ func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
errorMessage.TextStyle = fyne.TextStyle{Bold: true} errorMessage.TextStyle = fyne.TextStyle{Bold: true}
viewSettingForm := &SettingForm{ viewSettingForm := &SettingForm{
Language: v.app.GetLocalizerService().GetCurrentLanguage(), Language: v.app.GetLocalizerService().GetCurrentLanguage().Lang,
ThemeInfo: v.themeService.GetCurrentThemeInfo(), ThemeInfo: v.themeService.GetCurrentThemeInfo(),
} }
@@ -54,7 +55,7 @@ func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
viewSettingForm.Language = lang viewSettingForm.Language = lang
} }
}) })
selectLanguage.Selected = v.app.GetLocalizerService().GetCurrentLanguage().Title selectLanguage.Selected = v.app.GetLocalizerService().GetCurrentLanguage().Lang.Title
themeItems := []string{} themeItems := []string{}
themeByTitle := map[string]theme.ThemeInfoContract{} themeByTitle := map[string]theme.ThemeInfoContract{}
@@ -72,18 +73,24 @@ func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
form := &widget.Form{ form := &widget.Form{
Items: []*widget.FormItem{ Items: []*widget.FormItem{
{ {
Text: v.app.GetLocalizerService().GetMessage("menuSettingsLanguage"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "menuSettingsLanguage",
}),
Widget: selectLanguage, Widget: selectLanguage,
}, },
{ {
Text: v.app.GetLocalizerService().GetMessage("menuSettingsTheme"), Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "menuSettingsTheme",
}),
Widget: selectTheme, Widget: selectTheme,
}, },
{ {
Widget: errorMessage, Widget: errorMessage,
}, },
}, },
SubmitText: v.app.GetLocalizerService().GetMessage("save"), SubmitText: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "save",
}),
OnSubmit: func() { OnSubmit: func() {
err := save(viewSettingForm) err := save(viewSettingForm)
if err != nil { if err != nil {
@@ -93,9 +100,13 @@ func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
} }
if cancel != nil { if cancel != nil {
form.OnCancel = cancel form.OnCancel = cancel
form.CancelText = v.app.GetLocalizerService().GetMessage("cancel") form.CancelText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "cancel",
})
} }
messageHead := v.app.GetLocalizerService().GetMessage("settings") messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
MessageID: "settings",
})
v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", form)) v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", form))
} }

12
migration/migration.go Normal file
View File

@@ -0,0 +1,12 @@
package migration
import (
"go.etcd.io/bbolt"
)
func Run(db *bbolt.DB) error {
return db.Update(func(tx *bbolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("settings"))
return err
})
}

View File

@@ -1,8 +1,8 @@
package setting package setting
type DirectoryForSavingContract interface { type DirectoryForSavingContract interface {
GetDirectoryForSaving() string GetDirectoryForSaving() (string, error)
SaveDirectoryForSaving(path string) Setting SaveDirectoryForSaving(path string) (Setting, error)
} }
type DirectoryForSaving struct { type DirectoryForSaving struct {
@@ -13,10 +13,10 @@ func NewSettingDirectoryForSaving(settingRepository RepositoryContract) *Directo
return &DirectoryForSaving{settingRepository: settingRepository} return &DirectoryForSaving{settingRepository: settingRepository}
} }
func (setting DirectoryForSaving) GetDirectoryForSaving() string { func (setting DirectoryForSaving) GetDirectoryForSaving() (string, error) {
return setting.settingRepository.GetValue("directoryForSaving") return setting.settingRepository.GetValue("directoryForSaving")
} }
func (setting DirectoryForSaving) SaveDirectoryForSaving(path string) Setting { func (setting DirectoryForSaving) SaveDirectoryForSaving(path string) (Setting, error) {
return setting.settingRepository.CreateOrUpdate("directoryForSaving", path) return setting.settingRepository.CreateOrUpdate("directoryForSaving", path)
} }

View File

@@ -1,6 +1,6 @@
package setting package setting
type Setting struct { type Setting struct {
Code string Code string `json:"code"`
Value string Value string `json:"value"`
} }

View File

@@ -1,39 +1,82 @@
package setting package setting
import ( import (
"fyne.io/fyne/v2" "encoding/json"
"errors"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/db"
"go.etcd.io/bbolt"
) )
type RepositoryContract interface { type RepositoryContract interface {
Create(setting Setting) Setting Create(setting Setting) (Setting, error)
CreateOrUpdate(code string, value string) Setting CreateOrUpdate(code string, value string) (Setting, error)
GetValue(code string) string GetValue(code string) (value string, err error)
} }
type Repository struct { type Repository struct {
app fyne.App db *bbolt.DB
} }
func NewRepository(app fyne.App) *Repository { func NewRepository(db *bbolt.DB) *Repository {
return &Repository{ return &Repository{db}
app: app, }
func (r Repository) GetValue(code string) (value string, err error) {
var setting Setting
err = r.db.View(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte("settings"))
if b == nil {
return errors.New("bucket 'settings' not found")
} }
val := b.Get([]byte(code))
if val == nil {
return db.ErrRecordNotFound
}
return json.Unmarshal(val, &setting)
})
if err != nil {
return "", err
}
return setting.Value, nil
} }
func (r Repository) GetValue(code string) string { func (r Repository) Create(setting Setting) (Setting, error) {
return r.app.Preferences().String(code) err := r.db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte("settings"))
if b == nil {
return errors.New("bucket 'settings' not found")
}
data, err := json.Marshal(setting)
if err != nil {
return err
}
return b.Put([]byte(setting.Code), data)
})
return setting, err
} }
func (r Repository) Create(setting Setting) Setting { func (r Repository) CreateOrUpdate(code string, value string) (Setting, error) {
r.app.Preferences().SetString(setting.Code, setting.Value)
return setting
}
func (r Repository) CreateOrUpdate(code string, value string) Setting {
var setting Setting var setting Setting
setting.Code = code setting.Code = code
setting.Value = value setting.Value = value
r.app.Preferences().SetString(code, value) err := r.db.Update(func(tx *bbolt.Tx) error {
return setting b := tx.Bucket([]byte("settings"))
if b == nil {
return errors.New("bucket 'settings' not found")
}
data, err := json.Marshal(setting)
if err != nil {
return err
}
return b.Put([]byte(code), data)
})
return setting, err
} }

View File

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

View File

@@ -4,6 +4,7 @@ import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
fyneTheme "fyne.io/fyne/v2/theme" fyneTheme "fyne.io/fyne/v2/theme"
"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"
"image/color" "image/color"
) )
@@ -54,7 +55,10 @@ func (t theme) List() map[string]ThemeInfoContract {
} }
func (t theme) SetCurrentTheme(themeInfo ThemeInfoContract) error { func (t theme) SetCurrentTheme(themeInfo ThemeInfoContract) error {
_ = t.repository.Save(themeInfo.GetName()) _, err := t.repository.Save(themeInfo.GetName())
if err != nil {
return err
}
if themeInfo.GetName() == "default" { if themeInfo.GetName() == "default" {
t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme()) t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme())
@@ -92,18 +96,24 @@ func (inf themeInfo) GetVariant() fyne.ThemeVariant {
func getThemes(localizer kernel.LocalizerContract) map[string]ThemeInfoContract { func getThemes(localizer kernel.LocalizerContract) map[string]ThemeInfoContract {
themesNameDefault := &themeInfo{ themesNameDefault := &themeInfo{
name: "default", name: "default",
title: localizer.GetMessage("themesNameDefault"), title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameDefault",
}),
} }
themesNameLight := &themeInfo{ themesNameLight := &themeInfo{
name: "light", name: "light",
title: localizer.GetMessage("themesNameLight"), title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameLight",
}),
variant: fyneTheme.VariantLight, variant: fyneTheme.VariantLight,
} }
themesNameDark := &themeInfo{ themesNameDark := &themeInfo{
name: "dark", name: "dark",
title: localizer.GetMessage("themesNameDark"), title: localizer.GetMessage(&i18n.LocalizeConfig{
MessageID: "themesNameDark",
}),
variant: fyneTheme.VariantDark, variant: fyneTheme.VariantDark,
} }