Make it possible to drag and drop multiple files
It is now possible to add multiple files before sending them to the processing queue.
This commit is contained in:
parent
82167f042f
commit
84b36dd29e
@ -32,22 +32,22 @@ type Conversion struct {
|
|||||||
overwriteOutputFiles *overwriteOutputFiles
|
overwriteOutputFiles *overwriteOutputFiles
|
||||||
selectEncoder *selectEncoder
|
selectEncoder *selectEncoder
|
||||||
runConvert func(setting HandleConvertSetting)
|
runConvert func(setting HandleConvertSetting)
|
||||||
|
itemsToConvertService kernel.ItemsToConvertContract
|
||||||
}
|
}
|
||||||
|
|
||||||
type HandleConvertSetting struct {
|
type HandleConvertSetting struct {
|
||||||
FileInput kernel.File
|
|
||||||
DirectoryForSave string
|
DirectoryForSave string
|
||||||
OverwriteOutputFiles bool
|
OverwriteOutputFiles bool
|
||||||
Format string
|
Format string
|
||||||
Encoder encoder2.EncoderContract
|
Encoder encoder2.EncoderContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContract, runConvert func(setting HandleConvertSetting), settingDirectoryForSaving setting.DirectoryForSavingContract) *Conversion {
|
func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContract, runConvert func(setting HandleConvertSetting), settingDirectoryForSaving setting.DirectoryForSavingContract, itemsToConvertService kernel.ItemsToConvertContract) *Conversion {
|
||||||
conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
||||||
conversionMessage.TextSize = 16
|
conversionMessage.TextSize = 16
|
||||||
conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
|
conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
|
|
||||||
fileForConversion := newFileForConversion(app)
|
fileForConversion := newFileForConversion(app, itemsToConvertService)
|
||||||
directoryForSaving := newDirectoryForSaving(app, settingDirectoryForSaving)
|
directoryForSaving := newDirectoryForSaving(app, settingDirectoryForSaving)
|
||||||
overwriteOutputFiles := newOverwriteOutputFiles(app)
|
overwriteOutputFiles := newOverwriteOutputFiles(app)
|
||||||
selectEncoder := newSelectEncoder(app, formats)
|
selectEncoder := newSelectEncoder(app, formats)
|
||||||
@ -93,6 +93,7 @@ func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContr
|
|||||||
overwriteOutputFiles: overwriteOutputFiles,
|
overwriteOutputFiles: overwriteOutputFiles,
|
||||||
selectEncoder: selectEncoder,
|
selectEncoder: selectEncoder,
|
||||||
runConvert: runConvert,
|
runConvert: runConvert,
|
||||||
|
itemsToConvertService: itemsToConvertService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,20 +122,32 @@ func (c Conversion) changeEncoder(encoder encoder2.EncoderContract) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Conversion) AfterViewContent() {
|
func (c Conversion) AfterViewContent() {
|
||||||
|
if len(c.itemsToConvertService.GetItems()) == 0 {
|
||||||
c.form.form.Disable()
|
c.form.form.Disable()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Conversion) selectFileForConversion(err error) {
|
func (c Conversion) selectFileForConversion(err error) {
|
||||||
c.conversionMessage.Text = ""
|
c.conversionMessage.Text = ""
|
||||||
|
if len(c.itemsToConvertService.GetItems()) == 0 {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.form.form.Disable()
|
c.form.form.Disable()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.form.form.Enable()
|
c.form.form.Enable()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Conversion) submit() {
|
func (c Conversion) submit() {
|
||||||
|
if len(c.itemsToConvertService.GetItems()) == 0 {
|
||||||
|
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorNoFilesAddedForConversion",
|
||||||
|
})))
|
||||||
|
c.enableFormConversion()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.directoryForSaving.path) == 0 {
|
if len(c.directoryForSaving.path) == 0 {
|
||||||
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "errorSelectedFolderSave",
|
MessageID: "errorSelectedFolderSave",
|
||||||
@ -160,19 +173,18 @@ func (c Conversion) submit() {
|
|||||||
c.directoryForSaving.button.Disable()
|
c.directoryForSaving.button.Disable()
|
||||||
c.form.form.Disable()
|
c.form.form.Disable()
|
||||||
|
|
||||||
setting := HandleConvertSetting{
|
c.runConvert(HandleConvertSetting{
|
||||||
FileInput: *c.fileForConversion.file,
|
|
||||||
DirectoryForSave: c.directoryForSaving.path,
|
DirectoryForSave: c.directoryForSaving.path,
|
||||||
OverwriteOutputFiles: c.overwriteOutputFiles.IsChecked(),
|
OverwriteOutputFiles: c.overwriteOutputFiles.IsChecked(),
|
||||||
Format: c.selectEncoder.SelectFormat.Selected,
|
Format: c.selectEncoder.SelectFormat.Selected,
|
||||||
Encoder: c.selectEncoder.Encoder,
|
Encoder: c.selectEncoder.Encoder,
|
||||||
}
|
})
|
||||||
c.runConvert(setting)
|
|
||||||
c.enableFormConversion()
|
c.enableFormConversion()
|
||||||
|
|
||||||
c.fileForConversion.message.Text = ""
|
if len(c.itemsToConvertService.GetItems()) == 0 {
|
||||||
c.form.form.Disable()
|
c.form.form.Disable()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Conversion) enableFormConversion() {
|
func (c Conversion) enableFormConversion() {
|
||||||
c.fileForConversion.button.Enable()
|
c.fileForConversion.button.Enable()
|
||||||
@ -188,44 +200,49 @@ type fileForConversion struct {
|
|||||||
changeCallbacks map[int]func(err error)
|
changeCallbacks map[int]func(err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFileForConversion(app kernel.AppContract) *fileForConversion {
|
func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.ItemsToConvertContract) *fileForConversion {
|
||||||
|
message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
||||||
fileForConversion := &fileForConversion{
|
fileForConversion := &fileForConversion{
|
||||||
file: &kernel.File{},
|
message: message,
|
||||||
|
|
||||||
changeCallbacks: map[int]func(err error){},
|
changeCallbacks: map[int]func(err error){},
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "choose",
|
MessageID: "choose",
|
||||||
}) + "\n\r\n\r" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
}) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "or",
|
MessageID: "or",
|
||||||
}) + "\n\r\n\r" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
}) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "dragAndDrop1File",
|
MessageID: "dragAndDropFiles",
|
||||||
})
|
})
|
||||||
|
|
||||||
fileForConversion.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
|
||||||
fileForConversion.message.TextSize = 16
|
|
||||||
fileForConversion.message.TextStyle = fyne.TextStyle{Bold: true}
|
|
||||||
|
|
||||||
var locationURI fyne.ListableURI
|
var locationURI fyne.ListableURI
|
||||||
|
|
||||||
fileForConversion.button = widget.NewButton(buttonTitle, func() {
|
fileForConversion.button = widget.NewButton(buttonTitle, func() {
|
||||||
app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
|
app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
|
||||||
|
fyne.Do(func() {
|
||||||
|
fileForConversion.message.Text = ""
|
||||||
|
fileForConversion.message.Refresh()
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fyne.Do(func() {
|
||||||
fileForConversion.message.Text = err.Error()
|
fileForConversion.message.Text = err.Error()
|
||||||
setStringErrorStyle(fileForConversion.message)
|
fileForConversion.message.Refresh()
|
||||||
|
})
|
||||||
fileForConversion.eventSelectFile(err)
|
fileForConversion.eventSelectFile(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
|
||||||
|
|
||||||
fileForConversion.file.Path = r.URI().Path()
|
itemsToConvertService.Add(&kernel.File{
|
||||||
fileForConversion.file.Name = r.URI().Name()
|
Path: r.URI().Path(),
|
||||||
fileForConversion.file.Ext = r.URI().Extension()
|
Name: r.URI().Name(),
|
||||||
|
Ext: r.URI().Extension(),
|
||||||
fileForConversion.message.Text = r.URI().Path()
|
})
|
||||||
setStringSuccessStyle(fileForConversion.message)
|
|
||||||
|
|
||||||
fileForConversion.eventSelectFile(nil)
|
fileForConversion.eventSelectFile(nil)
|
||||||
|
|
||||||
@ -239,43 +256,41 @@ func newFileForConversion(app kernel.AppContract) *fileForConversion {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(uris) > 1 {
|
isError := false
|
||||||
fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
for _, uri := range uris {
|
||||||
MessageID: "errorDragAndDrop1File",
|
|
||||||
})
|
|
||||||
setStringErrorStyle(fileForConversion.message)
|
|
||||||
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
uri := uris[0]
|
|
||||||
info, err := os.Stat(uri.Path())
|
info, err := os.Stat(uri.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fileForConversion.message.Text = err.Error()
|
isError = true
|
||||||
setStringErrorStyle(fileForConversion.message)
|
continue
|
||||||
fileForConversion.eventSelectFile(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
isError = true
|
||||||
MessageID: "errorIsFolder",
|
continue
|
||||||
})
|
|
||||||
setStringErrorStyle(fileForConversion.message)
|
|
||||||
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileForConversion.file.Path = uri.Path()
|
itemsToConvertService.Add(&kernel.File{
|
||||||
fileForConversion.file.Name = uri.Name()
|
Path: uri.Path(),
|
||||||
fileForConversion.file.Ext = uri.Extension()
|
Name: uri.Name(),
|
||||||
|
Ext: uri.Extension(),
|
||||||
fileForConversion.message.Text = uri.Path()
|
})
|
||||||
setStringSuccessStyle(fileForConversion.message)
|
|
||||||
|
|
||||||
fileForConversion.eventSelectFile(nil)
|
fileForConversion.eventSelectFile(nil)
|
||||||
|
|
||||||
listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
|
listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
|
||||||
locationURI, _ = storage.ListerForURI(listableURI)
|
locationURI, _ = storage.ListerForURI(listableURI)
|
||||||
|
}
|
||||||
|
if isError {
|
||||||
|
fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorDragAndDropFile",
|
||||||
|
})
|
||||||
|
setStringErrorStyle(fileForConversion.message)
|
||||||
|
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
|
||||||
|
} else {
|
||||||
|
fyne.Do(func() {
|
||||||
|
fileForConversion.message.Text = ""
|
||||||
|
fileForConversion.message.Refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return fileForConversion
|
return fileForConversion
|
||||||
|
@ -25,6 +25,7 @@ type ConvertorHandler struct {
|
|||||||
errorView error2.ViewContract
|
errorView error2.ViewContract
|
||||||
convertorRepository convertor.RepositoryContract
|
convertorRepository convertor.RepositoryContract
|
||||||
settingDirectoryForSaving setting.DirectoryForSavingContract
|
settingDirectoryForSaving setting.DirectoryForSavingContract
|
||||||
|
itemsToConvertService kernel.ItemsToConvertContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConvertorHandler(
|
func NewConvertorHandler(
|
||||||
@ -33,6 +34,7 @@ func NewConvertorHandler(
|
|||||||
errorView error2.ViewContract,
|
errorView error2.ViewContract,
|
||||||
convertorRepository convertor.RepositoryContract,
|
convertorRepository convertor.RepositoryContract,
|
||||||
settingDirectoryForSaving setting.DirectoryForSavingContract,
|
settingDirectoryForSaving setting.DirectoryForSavingContract,
|
||||||
|
itemsToConvertService kernel.ItemsToConvertContract,
|
||||||
) *ConvertorHandler {
|
) *ConvertorHandler {
|
||||||
return &ConvertorHandler{
|
return &ConvertorHandler{
|
||||||
app: app,
|
app: app,
|
||||||
@ -40,6 +42,7 @@ func NewConvertorHandler(
|
|||||||
errorView: errorView,
|
errorView: errorView,
|
||||||
convertorRepository: convertorRepository,
|
convertorRepository: convertorRepository,
|
||||||
settingDirectoryForSaving: settingDirectoryForSaving,
|
settingDirectoryForSaving: settingDirectoryForSaving,
|
||||||
|
itemsToConvertService: itemsToConvertService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ func (h ConvertorHandler) MainConvertor() {
|
|||||||
h.errorView.PanicError(err)
|
h.errorView.PanicError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conversion := view.NewConversion(h.app, formats, h.runConvert, h.settingDirectoryForSaving)
|
conversion := view.NewConversion(h.app, formats, h.runConvert, h.settingDirectoryForSaving, h.itemsToConvertService)
|
||||||
h.convertorView.Main(conversion)
|
h.convertorView.Main(conversion)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -77,17 +80,27 @@ func (h ConvertorHandler) GetFfplayVersion() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
|
func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
|
||||||
|
h.app.GetWindow().GetLayout().GetRightTabs().SelectFileQueueTab()
|
||||||
|
|
||||||
|
for _, item := range h.itemsToConvertService.GetItems() {
|
||||||
|
file := item.GetFile()
|
||||||
|
if file == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
h.app.GetQueue().Add(&kernel.ConvertSetting{
|
h.app.GetQueue().Add(&kernel.ConvertSetting{
|
||||||
VideoFileInput: setting.FileInput,
|
VideoFileInput: *file,
|
||||||
VideoFileOut: kernel.File{
|
VideoFileOut: kernel.File{
|
||||||
Path: setting.DirectoryForSave + helper.PathSeparator() + setting.FileInput.Name + "." + setting.Format,
|
Path: setting.DirectoryForSave + helper.PathSeparator() + file.Name + "." + setting.Format,
|
||||||
Name: setting.FileInput.Name,
|
Name: file.Name,
|
||||||
Ext: "." + setting.Format,
|
Ext: "." + setting.Format,
|
||||||
},
|
},
|
||||||
OverwriteOutputFiles: setting.OverwriteOutputFiles,
|
OverwriteOutputFiles: setting.OverwriteOutputFiles,
|
||||||
Encoder: setting.Encoder,
|
Encoder: setting.Encoder,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
h.itemsToConvertService.AfterAddingQueue()
|
||||||
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) checkingFFPathUtilities() bool {
|
func (h ConvertorHandler) checkingFFPathUtilities() bool {
|
||||||
if h.checkingFFPath() == true {
|
if h.checkingFFPath() == true {
|
||||||
|
@ -12,6 +12,7 @@ type AppContract interface {
|
|||||||
GetQueue() QueueListContract
|
GetQueue() QueueListContract
|
||||||
GetLocalizerService() LocalizerContract
|
GetLocalizerService() LocalizerContract
|
||||||
GetConvertorService() ConvertorContract
|
GetConvertorService() ConvertorContract
|
||||||
|
GetFFplayService() FFplayContract
|
||||||
AfterClosing()
|
AfterClosing()
|
||||||
RunConvertor()
|
RunConvertor()
|
||||||
}
|
}
|
||||||
@ -23,25 +24,34 @@ type App struct {
|
|||||||
|
|
||||||
localizerService LocalizerContract
|
localizerService LocalizerContract
|
||||||
convertorService ConvertorContract
|
convertorService ConvertorContract
|
||||||
|
blockProgressbarService BlockProgressbarContract
|
||||||
|
ffplayService FFplayContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(
|
func NewApp(
|
||||||
metadata *fyne.AppMetadata,
|
metadata *fyne.AppMetadata,
|
||||||
localizerService LocalizerContract,
|
localizerService LocalizerContract,
|
||||||
queue QueueListContract,
|
queue QueueListContract,
|
||||||
queueLayoutObject QueueLayoutObjectContract,
|
ffplayService FFplayContract,
|
||||||
convertorService ConvertorContract,
|
convertorService ConvertorContract,
|
||||||
) *App {
|
) *App {
|
||||||
app.SetMetadata(*metadata)
|
app.SetMetadata(*metadata)
|
||||||
a := app.New()
|
a := app.New()
|
||||||
|
|
||||||
|
statusesText := GetBlockProgressbarStatusesText(localizerService)
|
||||||
|
blockProgressbarService := NewBlockProgressbar(statusesText, ffplayService)
|
||||||
|
rightTabsService := NewRightTabs(localizerService)
|
||||||
|
queueLayoutObject := NewQueueLayoutObject(queue, localizerService, ffplayService, rightTabsService, blockProgressbarService.GetContainer())
|
||||||
|
|
||||||
return &App{
|
return &App{
|
||||||
AppFyne: a,
|
AppFyne: a,
|
||||||
Window: newWindow(a.NewWindow("GUI for FFmpeg"), NewLayout(queueLayoutObject, localizerService)),
|
Window: newWindow(a.NewWindow("GUI for FFmpeg"), NewLayout(queueLayoutObject, localizerService, rightTabsService)),
|
||||||
Queue: queue,
|
Queue: queue,
|
||||||
|
|
||||||
localizerService: localizerService,
|
localizerService: localizerService,
|
||||||
convertorService: convertorService,
|
convertorService: convertorService,
|
||||||
|
blockProgressbarService: blockProgressbarService,
|
||||||
|
ffplayService: ffplayService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +75,10 @@ func (a App) GetConvertorService() ConvertorContract {
|
|||||||
return a.convertorService
|
return a.convertorService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a App) GetFFplayService() FFplayContract {
|
||||||
|
return a.ffplayService
|
||||||
|
}
|
||||||
|
|
||||||
func (a App) AfterClosing() {
|
func (a App) AfterClosing() {
|
||||||
for _, cmd := range a.convertorService.GetRunningProcesses() {
|
for _, cmd := range a.convertorService.GetRunningProcesses() {
|
||||||
_ = cmd.Process.Kill()
|
_ = cmd.Process.Kill()
|
||||||
@ -81,22 +95,33 @@ func (a App) RunConvertor() {
|
|||||||
}
|
}
|
||||||
queue.Status = StatusType(InProgress)
|
queue.Status = StatusType(InProgress)
|
||||||
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
||||||
|
if a.blockProgressbarService.GetContainer().Hidden {
|
||||||
|
a.blockProgressbarService.GetContainer().Show()
|
||||||
|
}
|
||||||
|
|
||||||
totalDuration, err := a.convertorService.GetTotalDuration(&queue.Setting.VideoFileInput)
|
totalDuration, err := a.convertorService.GetTotalDuration(&queue.Setting.VideoFileInput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
totalDuration = 0
|
totalDuration = 0
|
||||||
}
|
}
|
||||||
progress := a.Window.GetLayout().NewProgressbar(queueId, totalDuration)
|
|
||||||
|
progress := a.blockProgressbarService.GetProgressbar(
|
||||||
|
totalDuration,
|
||||||
|
queue.Setting.VideoFileInput.Path,
|
||||||
|
a.localizerService,
|
||||||
|
)
|
||||||
|
|
||||||
err = a.convertorService.RunConvert(*queue.Setting, progress)
|
err = a.convertorService.RunConvert(*queue.Setting, progress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
queue.Status = StatusType(Error)
|
queue.Status = StatusType(Error)
|
||||||
queue.Error = err
|
queue.Error = err
|
||||||
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
||||||
|
a.blockProgressbarService.ProcessEndedWithError(err.Error())
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
queue.Status = StatusType(Completed)
|
queue.Status = StatusType(Completed)
|
||||||
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
|
||||||
|
a.blockProgressbarService.ProcessEndedWithSuccess(queue.Setting.VideoFileOut.Path)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
151
kernel/items_to_convert.go
Normal file
151
kernel/items_to_convert.go
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fyne.io/fyne/v2"
|
||||||
|
"fyne.io/fyne/v2/canvas"
|
||||||
|
"fyne.io/fyne/v2/container"
|
||||||
|
"fyne.io/fyne/v2/theme"
|
||||||
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ItemsToConvertContract interface {
|
||||||
|
Add(file *File)
|
||||||
|
GetItems() map[int]ItemToConvertContract
|
||||||
|
AfterAddingQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemsToConvert struct {
|
||||||
|
nextId int
|
||||||
|
items map[int]ItemToConvertContract
|
||||||
|
itemsContainer *fyne.Container
|
||||||
|
ffplayService FFplayContract
|
||||||
|
isAutoRemove bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewItemsToConvert(itemsContainer *fyne.Container, ffplayService FFplayContract, localizerService LocalizerContract) *ItemsToConvert {
|
||||||
|
containerForItems := container.NewVBox()
|
||||||
|
ItemsToConvert := &ItemsToConvert{
|
||||||
|
nextId: 0,
|
||||||
|
items: map[int]ItemToConvertContract{},
|
||||||
|
itemsContainer: containerForItems,
|
||||||
|
ffplayService: ffplayService,
|
||||||
|
isAutoRemove: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
|
||||||
|
line.StrokeWidth = 5
|
||||||
|
checkboxAutoRemove := widget.NewCheck(localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "autoClearAfterAddingToQueue",
|
||||||
|
}), func(checked bool) {
|
||||||
|
ItemsToConvert.isAutoRemove = checked
|
||||||
|
})
|
||||||
|
checkboxAutoRemove.SetChecked(ItemsToConvert.isAutoRemove)
|
||||||
|
localizerService.AddChangeCallback("autoClearAfterAddingToQueue", func(text string) {
|
||||||
|
checkboxAutoRemove.Text = text
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonClear := widget.NewButton(localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "clearAll",
|
||||||
|
}), func() {
|
||||||
|
ItemsToConvert.clear()
|
||||||
|
})
|
||||||
|
buttonClear.Importance = widget.DangerImportance
|
||||||
|
localizerService.AddChangeCallback("clearAll", func(text string) {
|
||||||
|
buttonClear.Text = text
|
||||||
|
})
|
||||||
|
|
||||||
|
itemsContainer.Add(container.NewVBox(
|
||||||
|
container.NewPadded(),
|
||||||
|
container.NewBorder(nil, nil, nil, buttonClear, container.NewHScroll(checkboxAutoRemove)),
|
||||||
|
container.NewPadded(),
|
||||||
|
line,
|
||||||
|
container.NewPadded(),
|
||||||
|
containerForItems,
|
||||||
|
))
|
||||||
|
|
||||||
|
return ItemsToConvert
|
||||||
|
}
|
||||||
|
|
||||||
|
func (items *ItemsToConvert) Add(file *File) {
|
||||||
|
nextId := items.nextId
|
||||||
|
var content *fyne.Container
|
||||||
|
var buttonPlay *widget.Button
|
||||||
|
|
||||||
|
buttonPlay = widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
||||||
|
buttonPlay.Disable()
|
||||||
|
go func() {
|
||||||
|
_ = items.ffplayService.Run(FFplaySetting{
|
||||||
|
PathToFile: file.Path,
|
||||||
|
})
|
||||||
|
fyne.Do(func() {
|
||||||
|
buttonPlay.Enable()
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
|
||||||
|
buttonRemove := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameDelete), func() {
|
||||||
|
items.itemsContainer.Remove(content)
|
||||||
|
items.itemsContainer.Refresh()
|
||||||
|
delete(items.items, nextId)
|
||||||
|
})
|
||||||
|
buttonRemove.Importance = widget.DangerImportance
|
||||||
|
|
||||||
|
content = container.NewVBox(
|
||||||
|
container.NewBorder(
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
buttonPlay,
|
||||||
|
buttonRemove,
|
||||||
|
container.NewHScroll(widget.NewLabel(file.Name)),
|
||||||
|
),
|
||||||
|
container.NewHScroll(widget.NewLabel(file.Path)),
|
||||||
|
container.NewPadded(),
|
||||||
|
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
|
||||||
|
container.NewPadded(),
|
||||||
|
)
|
||||||
|
|
||||||
|
items.itemsContainer.Add(content)
|
||||||
|
items.items[nextId] = NewItemToConvert(file, content)
|
||||||
|
items.nextId++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (items *ItemsToConvert) GetItems() map[int]ItemToConvertContract {
|
||||||
|
return items.items
|
||||||
|
}
|
||||||
|
|
||||||
|
func (items *ItemsToConvert) AfterAddingQueue() {
|
||||||
|
if items.isAutoRemove {
|
||||||
|
items.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (items *ItemsToConvert) clear() {
|
||||||
|
items.itemsContainer.RemoveAll()
|
||||||
|
items.items = map[int]ItemToConvertContract{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemToConvertContract interface {
|
||||||
|
GetFile() *File
|
||||||
|
GetContent() *fyne.Container
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemToConvert struct {
|
||||||
|
file *File
|
||||||
|
content *fyne.Container
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewItemToConvert(file *File, content *fyne.Container) *ItemToConvert {
|
||||||
|
return &ItemToConvert{
|
||||||
|
file: file,
|
||||||
|
content: content,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (item ItemToConvert) GetFile() *File {
|
||||||
|
return item.file
|
||||||
|
}
|
||||||
|
|
||||||
|
func (item ItemToConvert) GetContent() *fyne.Container {
|
||||||
|
return item.content
|
||||||
|
}
|
167
kernel/layout.go
167
kernel/layout.go
@ -1,8 +1,6 @@
|
|||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/canvas"
|
"fyne.io/fyne/v2/canvas"
|
||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
@ -10,31 +8,31 @@ import (
|
|||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LayoutContract interface {
|
type LayoutContract interface {
|
||||||
SetContent(content fyne.CanvasObject) *fyne.Container
|
SetContent(content fyne.CanvasObject) *fyne.Container
|
||||||
NewProgressbar(queueId int, totalDuration float64) ProgressContract
|
|
||||||
ChangeQueueStatus(queueId int, queue *Queue)
|
ChangeQueueStatus(queueId int, queue *Queue)
|
||||||
|
GetRightTabs() RightTabsContract
|
||||||
}
|
}
|
||||||
|
|
||||||
type Layout struct {
|
type Layout struct {
|
||||||
layout *fyne.Container
|
layout *fyne.Container
|
||||||
queueLayoutObject QueueLayoutObjectContract
|
queueLayoutObject QueueLayoutObjectContract
|
||||||
localizerService LocalizerContract
|
localizerService LocalizerContract
|
||||||
|
rightTabsService RightTabsContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLayout(queueLayoutObject QueueLayoutObjectContract, localizerService LocalizerContract) *Layout {
|
func NewLayout(queueLayoutObject QueueLayoutObjectContract, localizerService LocalizerContract, rightTabsService RightTabsContract) *Layout {
|
||||||
layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), container.NewVScroll(queueLayoutObject.GetCanvasObject()))
|
layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), queueLayoutObject.GetCanvasObject())
|
||||||
|
|
||||||
return &Layout{
|
return &Layout{
|
||||||
layout: layout,
|
layout: layout,
|
||||||
queueLayoutObject: queueLayoutObject,
|
queueLayoutObject: queueLayoutObject,
|
||||||
localizerService: localizerService,
|
localizerService: localizerService,
|
||||||
|
rightTabsService: rightTabsService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,18 +41,16 @@ func (l Layout) SetContent(content fyne.CanvasObject) *fyne.Container {
|
|||||||
return l.layout
|
return l.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Layout) NewProgressbar(queueId int, totalDuration float64) ProgressContract {
|
|
||||||
progressbar := l.queueLayoutObject.GetProgressbar(queueId)
|
|
||||||
return NewProgress(totalDuration, progressbar, l.localizerService)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Layout) ChangeQueueStatus(queueId int, queue *Queue) {
|
func (l Layout) ChangeQueueStatus(queueId int, queue *Queue) {
|
||||||
l.queueLayoutObject.ChangeQueueStatus(queueId, queue)
|
l.queueLayoutObject.ChangeQueueStatus(queueId, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l Layout) GetRightTabs() RightTabsContract {
|
||||||
|
return l.rightTabsService
|
||||||
|
}
|
||||||
|
|
||||||
type QueueLayoutObjectContract interface {
|
type QueueLayoutObjectContract interface {
|
||||||
GetCanvasObject() fyne.CanvasObject
|
GetCanvasObject() fyne.CanvasObject
|
||||||
GetProgressbar(queueId int) *widget.ProgressBar
|
|
||||||
ChangeQueueStatus(queueId int, queue *Queue)
|
ChangeQueueStatus(queueId int, queue *Queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +59,7 @@ type QueueLayoutObject struct {
|
|||||||
|
|
||||||
queue QueueListContract
|
queue QueueListContract
|
||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
|
containerItems *fyne.Container
|
||||||
items map[int]QueueLayoutItem
|
items map[int]QueueLayoutItem
|
||||||
localizerService LocalizerContract
|
localizerService LocalizerContract
|
||||||
queueStatisticsFormat *queueStatisticsFormat
|
queueStatisticsFormat *queueStatisticsFormat
|
||||||
@ -71,7 +68,7 @@ type QueueLayoutObject struct {
|
|||||||
|
|
||||||
type QueueLayoutItem struct {
|
type QueueLayoutItem struct {
|
||||||
CanvasObject fyne.CanvasObject
|
CanvasObject fyne.CanvasObject
|
||||||
ProgressBar *widget.ProgressBar
|
BlockMessageError *container.Scroll
|
||||||
StatusMessage *canvas.Text
|
StatusMessage *canvas.Text
|
||||||
MessageError *canvas.Text
|
MessageError *canvas.Text
|
||||||
buttonPlay *widget.Button
|
buttonPlay *widget.Button
|
||||||
@ -79,7 +76,7 @@ type QueueLayoutItem struct {
|
|||||||
status *StatusContract
|
status *StatusContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract) *QueueLayoutObject {
|
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract, rightTabsService RightTabsContract, blockProgressbar *fyne.Container) *QueueLayoutObject {
|
||||||
title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
|
title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
|
||||||
title.TextStyle.Bold = true
|
title.TextStyle.Bold = true
|
||||||
|
|
||||||
@ -91,12 +88,27 @@ func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerCon
|
|||||||
items := map[int]QueueLayoutItem{}
|
items := map[int]QueueLayoutItem{}
|
||||||
queueStatisticsFormat := newQueueStatisticsFormat(localizerService, &items)
|
queueStatisticsFormat := newQueueStatisticsFormat(localizerService, &items)
|
||||||
|
|
||||||
queueLayoutObject := &QueueLayoutObject{
|
line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
|
||||||
queue: queue,
|
line.StrokeWidth = 5
|
||||||
container: container.NewVBox(
|
|
||||||
|
rightTabsService.GetFileQueueContainer().Add(container.NewVBox(
|
||||||
|
container.NewPadded(),
|
||||||
container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget),
|
container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget),
|
||||||
container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget),
|
container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget),
|
||||||
|
container.NewPadded(),
|
||||||
|
line,
|
||||||
|
container.NewPadded(),
|
||||||
|
))
|
||||||
|
queueLayoutObject := &QueueLayoutObject{
|
||||||
|
queue: queue,
|
||||||
|
container: container.NewBorder(
|
||||||
|
container.NewVBox(
|
||||||
|
blockProgressbar,
|
||||||
|
widget.NewSeparator(),
|
||||||
),
|
),
|
||||||
|
nil, nil, nil, container.NewVScroll(rightTabsService.GetTabs()),
|
||||||
|
),
|
||||||
|
containerItems: rightTabsService.GetFileQueueContainer(),
|
||||||
items: items,
|
items: items,
|
||||||
localizerService: localizerService,
|
localizerService: localizerService,
|
||||||
queueStatisticsFormat: queueStatisticsFormat,
|
queueStatisticsFormat: queueStatisticsFormat,
|
||||||
@ -112,31 +124,24 @@ func (o QueueLayoutObject) GetCanvasObject() fyne.CanvasObject {
|
|||||||
return o.container
|
return o.container
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o QueueLayoutObject) GetProgressbar(queueId int) *widget.ProgressBar {
|
|
||||||
if item, ok := o.items[queueId]; ok {
|
|
||||||
return item.ProgressBar
|
|
||||||
}
|
|
||||||
return widget.NewProgressBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o QueueLayoutObject) Add(id int, queue *Queue) {
|
func (o QueueLayoutObject) Add(id int, queue *Queue) {
|
||||||
progressBar := widget.NewProgressBar()
|
|
||||||
|
|
||||||
statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
|
statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
|
||||||
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
||||||
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
||||||
|
|
||||||
})
|
})
|
||||||
buttonPlay.Hide()
|
buttonPlay.Hide()
|
||||||
|
blockMessageError := container.NewHScroll(messageError)
|
||||||
|
blockMessageError.Hide()
|
||||||
|
|
||||||
content := container.NewVBox(
|
content := container.NewVBox(
|
||||||
container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
|
container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
|
||||||
progressBar,
|
container.NewHBox(
|
||||||
container.NewHScroll(container.NewHBox(
|
|
||||||
buttonPlay,
|
buttonPlay,
|
||||||
statusMessage,
|
statusMessage,
|
||||||
)),
|
),
|
||||||
container.NewHScroll(messageError),
|
blockMessageError,
|
||||||
|
container.NewPadded(),
|
||||||
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
|
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
|
||||||
container.NewPadded(),
|
container.NewPadded(),
|
||||||
)
|
)
|
||||||
@ -148,13 +153,13 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) {
|
|||||||
|
|
||||||
o.items[id] = QueueLayoutItem{
|
o.items[id] = QueueLayoutItem{
|
||||||
CanvasObject: content,
|
CanvasObject: content,
|
||||||
ProgressBar: progressBar,
|
|
||||||
StatusMessage: statusMessage,
|
StatusMessage: statusMessage,
|
||||||
|
BlockMessageError: blockMessageError,
|
||||||
MessageError: messageError,
|
MessageError: messageError,
|
||||||
buttonPlay: buttonPlay,
|
buttonPlay: buttonPlay,
|
||||||
status: &queue.Status,
|
status: &queue.Status,
|
||||||
}
|
}
|
||||||
o.container.Add(content)
|
o.containerItems.Add(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o QueueLayoutObject) Remove(id int) {
|
func (o QueueLayoutObject) Remove(id int) {
|
||||||
@ -177,6 +182,7 @@ func (o QueueLayoutObject) ChangeQueueStatus(queueId int, queue *Queue) {
|
|||||||
item.MessageError.Text = queue.Error.Error()
|
item.MessageError.Text = queue.Error.Error()
|
||||||
item.MessageError.Color = statusColor
|
item.MessageError.Color = statusColor
|
||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
|
item.BlockMessageError.Show()
|
||||||
item.MessageError.Refresh()
|
item.MessageError.Refresh()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -219,101 +225,6 @@ func (o QueueLayoutObject) getStatusTitle(status StatusContract) string {
|
|||||||
return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"})
|
return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"})
|
||||||
}
|
}
|
||||||
|
|
||||||
type Progress struct {
|
|
||||||
totalDuration float64
|
|
||||||
progressbar *widget.ProgressBar
|
|
||||||
protocol string
|
|
||||||
localizerService LocalizerContract
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
|
|
||||||
return Progress{
|
|
||||||
totalDuration: totalDuration,
|
|
||||||
progressbar: progressbar,
|
|
||||||
protocol: "pipe:",
|
|
||||||
localizerService: localizerService,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Progress) GetProtocole() string {
|
|
||||||
return p.protocol
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
|
|
||||||
isProcessCompleted := false
|
|
||||||
var errorText string
|
|
||||||
|
|
||||||
p.progressbar.Value = 0
|
|
||||||
p.progressbar.Max = p.totalDuration
|
|
||||||
fyne.Do(func() {
|
|
||||||
p.progressbar.Refresh()
|
|
||||||
})
|
|
||||||
progress := 0.0
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
scannerErr := bufio.NewReader(stdErr)
|
|
||||||
for {
|
|
||||||
line, _, err := scannerErr.ReadLine()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
data := strings.TrimSpace(string(line))
|
|
||||||
errorText = data
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
scannerOut := bufio.NewReader(stdOut)
|
|
||||||
for {
|
|
||||||
line, _, err := scannerOut.ReadLine()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
data := strings.TrimSpace(string(line))
|
|
||||||
if strings.Contains(data, "progress=end") {
|
|
||||||
p.progressbar.Value = p.totalDuration
|
|
||||||
fyne.Do(func() {
|
|
||||||
p.progressbar.Refresh()
|
|
||||||
})
|
|
||||||
isProcessCompleted = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
re := regexp.MustCompile(`frame=(\d+)`)
|
|
||||||
a := re.FindAllStringSubmatch(data, -1)
|
|
||||||
|
|
||||||
if len(a) > 0 && len(a[len(a)-1]) > 0 {
|
|
||||||
c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
progress = float64(c)
|
|
||||||
}
|
|
||||||
if p.progressbar.Value != progress {
|
|
||||||
p.progressbar.Value = progress
|
|
||||||
fyne.Do(func() {
|
|
||||||
p.progressbar.Refresh()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isProcessCompleted == false {
|
|
||||||
if len(errorText) == 0 {
|
|
||||||
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
|
|
||||||
MessageID: "errorConverter",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return errors.New(errorText)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type queueStatistics struct {
|
type queueStatistics struct {
|
||||||
widget *widget.Check
|
widget *widget.Check
|
||||||
title string
|
title string
|
||||||
|
254
kernel/progressbar.go
Normal file
254
kernel/progressbar.go
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fyne.io/fyne/v2"
|
||||||
|
"fyne.io/fyne/v2/canvas"
|
||||||
|
"fyne.io/fyne/v2/container"
|
||||||
|
"fyne.io/fyne/v2/theme"
|
||||||
|
"fyne.io/fyne/v2/widget"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
|
"image/color"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlockProgressbarContract interface {
|
||||||
|
GetContainer() *fyne.Container
|
||||||
|
GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress
|
||||||
|
ProcessEndedWithError(errorText string)
|
||||||
|
ProcessEndedWithSuccess(filePath string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockProgressbar struct {
|
||||||
|
container *fyne.Container
|
||||||
|
label *widget.Label
|
||||||
|
progressbar *widget.ProgressBar
|
||||||
|
errorBlock *container.Scroll
|
||||||
|
messageError *canvas.Text
|
||||||
|
statusMessage *canvas.Text
|
||||||
|
buttonPlay *widget.Button
|
||||||
|
statusesText *BlockProgressbarStatusesText
|
||||||
|
ffplayService FFplayContract
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlockProgressbar(statusesText *BlockProgressbarStatusesText, ffplayService FFplayContract) *BlockProgressbar {
|
||||||
|
label := widget.NewLabel("")
|
||||||
|
progressbar := widget.NewProgressBar()
|
||||||
|
|
||||||
|
statusMessage := canvas.NewText("", theme.Color(theme.ColorNamePrimary))
|
||||||
|
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
||||||
|
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
||||||
|
|
||||||
|
})
|
||||||
|
buttonPlay.Hide()
|
||||||
|
|
||||||
|
errorBlock := container.NewHScroll(messageError)
|
||||||
|
errorBlock.Hide()
|
||||||
|
|
||||||
|
content := container.NewVBox(
|
||||||
|
container.NewHScroll(label),
|
||||||
|
progressbar,
|
||||||
|
container.NewHScroll(container.NewHBox(
|
||||||
|
buttonPlay,
|
||||||
|
statusMessage,
|
||||||
|
)),
|
||||||
|
errorBlock,
|
||||||
|
)
|
||||||
|
content.Hide()
|
||||||
|
|
||||||
|
return &BlockProgressbar{
|
||||||
|
container: content,
|
||||||
|
label: label,
|
||||||
|
progressbar: progressbar,
|
||||||
|
errorBlock: errorBlock,
|
||||||
|
messageError: messageError,
|
||||||
|
statusMessage: statusMessage,
|
||||||
|
buttonPlay: buttonPlay,
|
||||||
|
statusesText: statusesText,
|
||||||
|
ffplayService: ffplayService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (block BlockProgressbar) GetContainer() *fyne.Container {
|
||||||
|
return block.container
|
||||||
|
}
|
||||||
|
|
||||||
|
func (block BlockProgressbar) GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress {
|
||||||
|
block.label.Text = filePath
|
||||||
|
block.statusMessage.Color = theme.Color(theme.ColorNamePrimary)
|
||||||
|
block.statusMessage.Text = block.statusesText.inProgress
|
||||||
|
block.messageError.Text = ""
|
||||||
|
fyne.Do(func() {
|
||||||
|
block.buttonPlay.Hide()
|
||||||
|
if block.errorBlock.Visible() {
|
||||||
|
block.errorBlock.Hide()
|
||||||
|
}
|
||||||
|
block.statusMessage.Refresh()
|
||||||
|
block.container.Refresh()
|
||||||
|
block.errorBlock.Refresh()
|
||||||
|
})
|
||||||
|
|
||||||
|
block.progressbar.Value = 0
|
||||||
|
return NewProgress(totalDuration, block.progressbar, localizerService)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (block BlockProgressbar) ProcessEndedWithError(errorText string) {
|
||||||
|
fyne.Do(func() {
|
||||||
|
block.statusMessage.Color = theme.Color(theme.ColorNameError)
|
||||||
|
block.statusMessage.Text = block.statusesText.error
|
||||||
|
block.messageError.Text = errorText
|
||||||
|
block.errorBlock.Show()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (block BlockProgressbar) ProcessEndedWithSuccess(filePath string) {
|
||||||
|
fyne.Do(func() {
|
||||||
|
block.statusMessage.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
|
||||||
|
block.statusMessage.Text = block.statusesText.completed
|
||||||
|
block.buttonPlay.Show()
|
||||||
|
block.buttonPlay.OnTapped = func() {
|
||||||
|
block.buttonPlay.Disable()
|
||||||
|
go func() {
|
||||||
|
_ = block.ffplayService.Run(FFplaySetting{
|
||||||
|
PathToFile: filePath,
|
||||||
|
})
|
||||||
|
fyne.Do(func() {
|
||||||
|
block.buttonPlay.Enable()
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Progress struct {
|
||||||
|
totalDuration float64
|
||||||
|
progressbar *widget.ProgressBar
|
||||||
|
protocol string
|
||||||
|
localizerService LocalizerContract
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
|
||||||
|
return Progress{
|
||||||
|
totalDuration: totalDuration,
|
||||||
|
progressbar: progressbar,
|
||||||
|
protocol: "pipe:",
|
||||||
|
localizerService: localizerService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Progress) GetProtocole() string {
|
||||||
|
return p.protocol
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
|
||||||
|
isProcessCompleted := false
|
||||||
|
var errorText string
|
||||||
|
|
||||||
|
p.progressbar.Value = 0
|
||||||
|
p.progressbar.Max = p.totalDuration
|
||||||
|
fyne.Do(func() {
|
||||||
|
p.progressbar.Refresh()
|
||||||
|
})
|
||||||
|
progress := 0.0
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
scannerErr := bufio.NewReader(stdErr)
|
||||||
|
for {
|
||||||
|
line, _, err := scannerErr.ReadLine()
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data := strings.TrimSpace(string(line))
|
||||||
|
errorText = data
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
scannerOut := bufio.NewReader(stdOut)
|
||||||
|
for {
|
||||||
|
line, _, err := scannerOut.ReadLine()
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data := strings.TrimSpace(string(line))
|
||||||
|
if strings.Contains(data, "progress=end") {
|
||||||
|
p.progressbar.Value = p.totalDuration
|
||||||
|
fyne.Do(func() {
|
||||||
|
p.progressbar.Refresh()
|
||||||
|
})
|
||||||
|
isProcessCompleted = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
re := regexp.MustCompile(`frame=(\d+)`)
|
||||||
|
a := re.FindAllStringSubmatch(data, -1)
|
||||||
|
|
||||||
|
if len(a) > 0 && len(a[len(a)-1]) > 0 {
|
||||||
|
c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
progress = float64(c)
|
||||||
|
}
|
||||||
|
if p.progressbar.Value != progress {
|
||||||
|
p.progressbar.Value = progress
|
||||||
|
fyne.Do(func() {
|
||||||
|
p.progressbar.Refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isProcessCompleted == false {
|
||||||
|
if len(errorText) == 0 {
|
||||||
|
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorConverter",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return errors.New(errorText)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockProgressbarStatusesText struct {
|
||||||
|
inProgress string
|
||||||
|
completed string
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText {
|
||||||
|
statusesText := &BlockProgressbarStatusesText{
|
||||||
|
inProgress: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "inProgressQueue",
|
||||||
|
}),
|
||||||
|
completed: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "completedQueue",
|
||||||
|
}),
|
||||||
|
error: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorQueue",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
localizerService.AddChangeCallback("inProgressQueue", func(text string) {
|
||||||
|
statusesText.inProgress = text
|
||||||
|
})
|
||||||
|
|
||||||
|
localizerService.AddChangeCallback("completedQueue", func(text string) {
|
||||||
|
statusesText.completed = text
|
||||||
|
})
|
||||||
|
|
||||||
|
localizerService.AddChangeCallback("errorQueue", func(text string) {
|
||||||
|
statusesText.error = text
|
||||||
|
})
|
||||||
|
|
||||||
|
return statusesText
|
||||||
|
}
|
76
kernel/right_tabs.go
Normal file
76
kernel/right_tabs.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fyne.io/fyne/v2"
|
||||||
|
"fyne.io/fyne/v2/container"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RightTabsContract interface {
|
||||||
|
GetTabs() *container.AppTabs
|
||||||
|
GetAddedFilesContainer() *fyne.Container
|
||||||
|
GetFileQueueContainer() *fyne.Container
|
||||||
|
SelectFileQueueTab()
|
||||||
|
SelectAddedFilesTab()
|
||||||
|
}
|
||||||
|
|
||||||
|
type RightTabs struct {
|
||||||
|
tabs *container.AppTabs
|
||||||
|
|
||||||
|
addedFilesContainer *fyne.Container
|
||||||
|
addedFilesTab *container.TabItem
|
||||||
|
|
||||||
|
fileQueueContainer *fyne.Container
|
||||||
|
fileQueueTab *container.TabItem
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRightTabs(localizerService LocalizerContract) *RightTabs {
|
||||||
|
addedFilesContainer := container.NewVBox()
|
||||||
|
addedFilesTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "addedFilesTitle"}), addedFilesContainer)
|
||||||
|
localizerService.AddChangeCallback("addedFilesTitle", func(text string) {
|
||||||
|
addedFilesTab.Text = text
|
||||||
|
})
|
||||||
|
|
||||||
|
fileQueueContainer := container.NewVBox()
|
||||||
|
fileQueueTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "fileQueueTitle"}), fileQueueContainer)
|
||||||
|
localizerService.AddChangeCallback("fileQueueTitle", func(text string) {
|
||||||
|
fileQueueTab.Text = text
|
||||||
|
})
|
||||||
|
|
||||||
|
tabs := container.NewAppTabs(
|
||||||
|
addedFilesTab,
|
||||||
|
fileQueueTab,
|
||||||
|
)
|
||||||
|
|
||||||
|
return &RightTabs{
|
||||||
|
tabs: tabs,
|
||||||
|
addedFilesContainer: addedFilesContainer,
|
||||||
|
addedFilesTab: addedFilesTab,
|
||||||
|
fileQueueContainer: fileQueueContainer,
|
||||||
|
fileQueueTab: fileQueueTab,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t RightTabs) GetTabs() *container.AppTabs {
|
||||||
|
return t.tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t RightTabs) GetAddedFilesContainer() *fyne.Container {
|
||||||
|
return t.addedFilesContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t RightTabs) GetFileQueueContainer() *fyne.Container {
|
||||||
|
return t.fileQueueContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t RightTabs) SelectFileQueueTab() {
|
||||||
|
fyne.Do(func() {
|
||||||
|
t.tabs.Select(t.fileQueueTab)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t RightTabs) SelectAddedFilesTab() {
|
||||||
|
fyne.Do(func() {
|
||||||
|
t.tabs.Select(t.addedFilesTab)
|
||||||
|
})
|
||||||
|
}
|
@ -10,6 +10,14 @@ other = "About"
|
|||||||
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
|
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
|
||||||
other = "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself."
|
other = "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself."
|
||||||
|
|
||||||
|
[addedFilesTitle]
|
||||||
|
hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
|
||||||
|
other = "Added files"
|
||||||
|
|
||||||
|
[autoClearAfterAddingToQueue]
|
||||||
|
hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
|
||||||
|
other = "Auto-clear after adding to queue"
|
||||||
|
|
||||||
[buttonDownloadFFmpeg]
|
[buttonDownloadFFmpeg]
|
||||||
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
|
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
|
||||||
other = "Download FFmpeg automatically"
|
other = "Download FFmpeg automatically"
|
||||||
@ -38,6 +46,10 @@ other = "Allow file to be overwritten"
|
|||||||
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
|
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
|
||||||
other = "choose"
|
other = "choose"
|
||||||
|
|
||||||
|
[clearAll]
|
||||||
|
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
|
||||||
|
other = "Clear List"
|
||||||
|
|
||||||
[completedQueue]
|
[completedQueue]
|
||||||
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
|
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
|
||||||
other = "Completed"
|
other = "Completed"
|
||||||
@ -62,9 +74,9 @@ other = "Will be downloaded from the site:"
|
|||||||
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
|
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
|
||||||
other = "Downloading..."
|
other = "Downloading..."
|
||||||
|
|
||||||
[dragAndDrop1File]
|
[dragAndDropFiles]
|
||||||
hash = "sha1-7259670822df1cc92ef5f06ed3c0e9407746975a"
|
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
|
||||||
other = "drag and drop 1 file"
|
other = "drag and drop files"
|
||||||
|
|
||||||
[encoderGroupAudio]
|
[encoderGroupAudio]
|
||||||
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
|
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
|
||||||
@ -226,9 +238,9 @@ other = "could not create file 'database' in folder 'data'"
|
|||||||
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
|
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
|
||||||
other = "Could not open configuration file.\nMake sure another copy of the program is not running!"
|
other = "Could not open configuration file.\nMake sure another copy of the program is not running!"
|
||||||
|
|
||||||
[errorDragAndDrop1File]
|
[errorDragAndDropFile]
|
||||||
hash = "sha1-a8edb5cbd622f3ce4ec07a2377e22ec5fad4491b"
|
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
|
||||||
other = "You can only drag and drop 1 file."
|
other = "Not all files were added"
|
||||||
|
|
||||||
[errorFFmpeg]
|
[errorFFmpeg]
|
||||||
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
|
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
|
||||||
@ -254,9 +266,9 @@ other = "this is not FFprobe"
|
|||||||
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
|
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
|
||||||
other = "Failed to determine FFprobe version"
|
other = "Failed to determine FFprobe version"
|
||||||
|
|
||||||
[errorIsFolder]
|
[errorNoFilesAddedForConversion]
|
||||||
hash = "sha1-f937d090b6e320957514d850657cdf2f911dc6aa"
|
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
|
||||||
other = "You can only drag and drop a file"
|
other = "There are no files to convert"
|
||||||
|
|
||||||
[errorQueue]
|
[errorQueue]
|
||||||
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
|
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
|
||||||
@ -290,6 +302,10 @@ other = "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**
|
|||||||
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
|
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
|
||||||
other = "File:"
|
other = "File:"
|
||||||
|
|
||||||
|
[fileQueueTitle]
|
||||||
|
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
|
||||||
|
other = "Queue"
|
||||||
|
|
||||||
[formPreset]
|
[formPreset]
|
||||||
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
|
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
|
||||||
other = "Preset"
|
other = "Preset"
|
||||||
|
@ -10,6 +10,14 @@ other = "Бағдарлама туралы"
|
|||||||
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
|
hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
|
||||||
other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін."
|
other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін."
|
||||||
|
|
||||||
|
[addedFilesTitle]
|
||||||
|
hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
|
||||||
|
other = "Қосылған файлдар"
|
||||||
|
|
||||||
|
[autoClearAfterAddingToQueue]
|
||||||
|
hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
|
||||||
|
other = "Кезекке қосқаннан кейін тазалаңыз"
|
||||||
|
|
||||||
[buttonDownloadFFmpeg]
|
[buttonDownloadFFmpeg]
|
||||||
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
|
hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
|
||||||
other = "FFmpeg автоматты түрде жүктеп алыңыз"
|
other = "FFmpeg автоматты түрде жүктеп алыңыз"
|
||||||
@ -38,6 +46,10 @@ other = "Файлды қайта жазуға рұқсат беріңіз"
|
|||||||
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
|
hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
|
||||||
other = "таңдау"
|
other = "таңдау"
|
||||||
|
|
||||||
|
[clearAll]
|
||||||
|
hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
|
||||||
|
other = "Тізімді өшіру"
|
||||||
|
|
||||||
[completedQueue]
|
[completedQueue]
|
||||||
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
|
hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
|
||||||
other = "Дайын"
|
other = "Дайын"
|
||||||
@ -62,9 +74,9 @@ other = "Сайттан жүктеледі:"
|
|||||||
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
|
hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
|
||||||
other = "Жүктеп алынуда..."
|
other = "Жүктеп алынуда..."
|
||||||
|
|
||||||
[dragAndDrop1File]
|
[dragAndDropFiles]
|
||||||
hash = "sha1-7259670822df1cc92ef5f06ed3c0e9407746975a"
|
hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
|
||||||
other = "1 файлды сүйреңіз"
|
other = "файлдарды сүйреп апарыңыз"
|
||||||
|
|
||||||
[encoderGroupAudio]
|
[encoderGroupAudio]
|
||||||
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
|
hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
|
||||||
@ -226,9 +238,9 @@ other = "'data' қалтасында 'database' файлын жасау мүмк
|
|||||||
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
|
hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
|
||||||
other = "Конфигурация файлын аша алмады.\nБағдарламаның басқа көшірмесі іске қосылмағанына көз жеткізіңіз!"
|
other = "Конфигурация файлын аша алмады.\nБағдарламаның басқа көшірмесі іске қосылмағанына көз жеткізіңіз!"
|
||||||
|
|
||||||
[errorDragAndDrop1File]
|
[errorDragAndDropFile]
|
||||||
hash = "sha1-a8edb5cbd622f3ce4ec07a2377e22ec5fad4491b"
|
hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
|
||||||
other = "Тек 1 файлды сүйреп апаруға болады"
|
other = "Барлық файлдар қосылмаған"
|
||||||
|
|
||||||
[errorFFmpeg]
|
[errorFFmpeg]
|
||||||
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
|
hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
|
||||||
@ -254,9 +266,9 @@ other = "бұл FFprobe емес"
|
|||||||
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
|
hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
|
||||||
other = "FFprobe нұсқасын анықтау мүмкін болмады"
|
other = "FFprobe нұсқасын анықтау мүмкін болмады"
|
||||||
|
|
||||||
[errorIsFolder]
|
[errorNoFilesAddedForConversion]
|
||||||
hash = "sha1-f937d090b6e320957514d850657cdf2f911dc6aa"
|
hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
|
||||||
other = "Тек файлды сүйреп апаруға болады"
|
other = "Түрлендіруге арналған файлдар жоқ"
|
||||||
|
|
||||||
[errorQueue]
|
[errorQueue]
|
||||||
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
|
hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
|
||||||
@ -290,6 +302,10 @@ other = "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын
|
|||||||
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
|
hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
|
||||||
other = "Файл:"
|
other = "Файл:"
|
||||||
|
|
||||||
|
[fileQueueTitle]
|
||||||
|
hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
|
||||||
|
other = "Кезек"
|
||||||
|
|
||||||
[formPreset]
|
[formPreset]
|
||||||
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
|
hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
|
||||||
other = "Алдын ала орнатылған"
|
other = "Алдын ала орнатылған"
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
AlsoUsedProgram = "Также в программе используется:"
|
AlsoUsedProgram = "Также в программе используется:"
|
||||||
about = "О программе"
|
about = "О программе"
|
||||||
aboutText = "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg."
|
aboutText = "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg."
|
||||||
|
addedFilesTitle = "Добавленные файлы"
|
||||||
|
autoClearAfterAddingToQueue = "Очищать после добавления в очередь"
|
||||||
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
|
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
|
||||||
buttonForSelectedDirTitle = "Сохранить в папку:"
|
buttonForSelectedDirTitle = "Сохранить в папку:"
|
||||||
cancel = "Отмена"
|
cancel = "Отмена"
|
||||||
@ -8,13 +10,14 @@ changeFFPath = "FFmpeg, FFprobe и FFplay"
|
|||||||
changeLanguage = "Поменять язык"
|
changeLanguage = "Поменять язык"
|
||||||
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
|
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
|
||||||
choose = "выбрать"
|
choose = "выбрать"
|
||||||
|
clearAll = "Очистить список"
|
||||||
completedQueue = "Готово"
|
completedQueue = "Готово"
|
||||||
converterVideoFilesSubmitTitle = "Конвертировать"
|
converterVideoFilesSubmitTitle = "Конвертировать"
|
||||||
converterVideoFilesTitle = "Конвертер видео, аудио и картинок"
|
converterVideoFilesTitle = "Конвертер видео, аудио и картинок"
|
||||||
download = "Скачать"
|
download = "Скачать"
|
||||||
downloadFFmpegFromSite = "Будет скачано с сайта:"
|
downloadFFmpegFromSite = "Будет скачано с сайта:"
|
||||||
downloadRun = "Скачивается..."
|
downloadRun = "Скачивается..."
|
||||||
dragAndDrop1File = "перетащить 1 файл"
|
dragAndDropFiles = "перетащить файлы"
|
||||||
encoderGroupAudio = "Аудио"
|
encoderGroupAudio = "Аудио"
|
||||||
encoderGroupImage = "Картинки"
|
encoderGroupImage = "Картинки"
|
||||||
encoderGroupVideo = "Видео"
|
encoderGroupVideo = "Видео"
|
||||||
@ -55,14 +58,14 @@ error = "Произошла ошибка!"
|
|||||||
errorConverter = "не смогли отконвертировать видео"
|
errorConverter = "не смогли отконвертировать видео"
|
||||||
errorDatabase = "не смогли создать файл 'database' в папке 'data'"
|
errorDatabase = "не смогли создать файл 'database' в папке 'data'"
|
||||||
errorDatabaseTimeout = "Не смогли открыть файл конфигурации.\nУбедитесь, что другая копия программы не запущена!"
|
errorDatabaseTimeout = "Не смогли открыть файл конфигурации.\nУбедитесь, что другая копия программы не запущена!"
|
||||||
errorDragAndDrop1File = "Можно перетащить только 1 файл"
|
errorDragAndDropFile = "Не все файлы добавились"
|
||||||
errorFFmpeg = "это не FFmpeg"
|
errorFFmpeg = "это не FFmpeg"
|
||||||
errorFFmpegVersion = "Не смогли определить версию FFmpeg"
|
errorFFmpegVersion = "Не смогли определить версию FFmpeg"
|
||||||
errorFFplay = "это не FFplay"
|
errorFFplay = "это не FFplay"
|
||||||
errorFFplayVersion = "Не смогли определить версию FFplay"
|
errorFFplayVersion = "Не смогли определить версию FFplay"
|
||||||
errorFFprobe = "это не FFprobe"
|
errorFFprobe = "это не FFprobe"
|
||||||
errorFFprobeVersion = "Не смогли определить версию FFprobe"
|
errorFFprobeVersion = "Не смогли определить версию FFprobe"
|
||||||
errorIsFolder = "Можно перетаскивать только файл"
|
errorNoFilesAddedForConversion = "Нет файлов для конвертации"
|
||||||
errorQueue = "Ошибка"
|
errorQueue = "Ошибка"
|
||||||
errorSelectedEncoder = "Конвертер не выбран"
|
errorSelectedEncoder = "Конвертер не выбран"
|
||||||
errorSelectedFolderSave = "Папка для сохранения не выбрана!"
|
errorSelectedFolderSave = "Папка для сохранения не выбрана!"
|
||||||
@ -71,6 +74,7 @@ exit = "Выход"
|
|||||||
ffmpegLGPL = "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."
|
ffmpegLGPL = "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."
|
||||||
ffmpegTrademark = "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**."
|
ffmpegTrademark = "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**."
|
||||||
fileForConversionTitle = "Файл:"
|
fileForConversionTitle = "Файл:"
|
||||||
|
fileQueueTitle = "Очередь"
|
||||||
formPreset = "Предустановка"
|
formPreset = "Предустановка"
|
||||||
gratitude = "Благодарность"
|
gratitude = "Благодарность"
|
||||||
gratitudeText = "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:"
|
gratitudeText = "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:"
|
||||||
|
9
main.go
9
main.go
@ -46,7 +46,7 @@ func init() {
|
|||||||
appMetadata,
|
appMetadata,
|
||||||
localizerService,
|
localizerService,
|
||||||
queue,
|
queue,
|
||||||
kernel.NewQueueLayoutObject(queue, localizerService, ffplayService),
|
ffplayService,
|
||||||
convertorService,
|
convertorService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -108,7 +108,12 @@ func main() {
|
|||||||
|
|
||||||
localizerView := localizer.NewView(application)
|
localizerView := localizer.NewView(application)
|
||||||
convertorView := convertor.NewView(application)
|
convertorView := convertor.NewView(application)
|
||||||
convertorHandler := handler.NewConvertorHandler(application, convertorView, errorView, convertorRepository, settingDirectoryForSaving)
|
itemsToConvertService := kernel.NewItemsToConvert(
|
||||||
|
application.GetWindow().GetLayout().GetRightTabs().GetAddedFilesContainer(),
|
||||||
|
application.GetFFplayService(),
|
||||||
|
application.GetLocalizerService(),
|
||||||
|
)
|
||||||
|
convertorHandler := handler.NewConvertorHandler(application, convertorView, errorView, convertorRepository, settingDirectoryForSaving, itemsToConvertService)
|
||||||
|
|
||||||
themeRepository := theme.NewRepository(settingRepository)
|
themeRepository := theme.NewRepository(settingRepository)
|
||||||
themeService := theme.NewTheme(application, themeRepository)
|
themeService := theme.NewTheme(application, themeRepository)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user