Made it so that files for conversion are added to the queue.

This commit is contained in:
Leonid Nikitin 2025-06-08 20:42:43 +05:00
parent df8095fb16
commit 29ca392880
Signed by: kor-elf
GPG Key ID: DAB5355A11C22541
6 changed files with 171 additions and 21 deletions

View File

@ -67,6 +67,7 @@ func NewQueueList() QueueListContract {
return &queueList{ return &queueList{
currentKey: 0, currentKey: 0,
items: map[int]*Queue{}, items: map[int]*Queue{},
queue: map[int]int{},
queueListener: map[int]QueueListenerContract{}, queueListener: map[int]QueueListenerContract{},
} }
} }

View File

@ -1,9 +1,12 @@
package controller package controller
import ( import (
"errors"
"fyne.io/fyne/v2/lang"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/download/service" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/download/service"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
) )
func (c *controller) convertor() { func (c *controller) convertor() {
@ -19,6 +22,7 @@ func (c *controller) convertor() {
c.app.GetSetting().GetDirectoryForSaving(), c.app.GetSetting().GetDirectoryForSaving(),
c.setDirectoryForSaving, c.setDirectoryForSaving,
formats, formats,
c.addToConversion,
) )
c.window.SetContent(content) c.window.SetContent(content)
} }
@ -32,6 +36,33 @@ func (c *controller) setDirectoryForSaving(path string) {
c.app.GetSetting().SetDirectoryForSaving(path) c.app.GetSetting().SetDirectoryForSaving(path)
} }
func (c *controller) addToConversion(convertSetting view.ConvertSetting) error {
if len(c.app.GetItemsToConvert().GetItems()) == 0 {
return errors.New(lang.L("errorNoFilesAddedForConversion"))
}
c.window.GetLayout().GetRContainer().SelectFileQueueTab()
for _, item := range c.app.GetItemsToConvert().GetItems() {
file := item.GetFile()
if file == nil {
continue
}
c.app.GetQueueService().Add(&ffmpeg.ConvertSetting{
FileInput: *file,
FileOut: ffmpeg.File{
Path: convertSetting.DirectoryForSave + utils.PathSeparator() + file.Name + "." + convertSetting.Format,
Name: file.Name,
Ext: "." + convertSetting.Format,
},
OverwriteOutputFiles: convertSetting.OverwriteOutputFiles,
Encoder: convertSetting.Encoder,
})
}
c.app.GetItemsToConvert().AfterAddingQueue()
return nil
}
func (c *controller) settingConvertor(isAllowCancellation bool) { func (c *controller) settingConvertor(isAllowCancellation bool) {
ffmpegPath := c.app.GetFFmpegService().GetFFmpegPath() ffmpegPath := c.app.GetFFmpegService().GetFFmpegPath()
ffprobePath := c.app.GetFFmpegService().GetFFprobePath() ffprobePath := c.app.GetFFmpegService().GetFFprobePath()

View File

@ -18,7 +18,7 @@ type controller struct {
func NewController(app application.AppContract) ControllerContract { func NewController(app application.AppContract) ControllerContract {
fyneWindow := app.FyneApp().NewWindow(app.FyneApp().Metadata().Name) fyneWindow := app.FyneApp().NewWindow(app.FyneApp().Metadata().Name)
queueLayout := window.NewQueueLayout() queueLayout := window.NewQueueLayout(app.GetFFmpegService())
app.GetQueueService().AddListener(queueLayout) app.GetQueueService().AddListener(queueLayout)
return &controller{ return &controller{

View File

@ -14,8 +14,8 @@ type File struct {
} }
type ConvertSetting struct { type ConvertSetting struct {
VideoFileInput File FileInput File
VideoFileOut File FileOut File
OverwriteOutputFiles bool OverwriteOutputFiles bool
Encoder encoder.EncoderContract Encoder encoder.EncoderContract
} }

View File

@ -148,19 +148,20 @@ func newFormConvertor(
directoryForSavingButton.button.Disable() directoryForSavingButton.button.Disable()
formConvertor.form.Disable() formConvertor.form.Disable()
err := addToConversion(ConvertSetting{ fyne.Do(func() {
DirectoryForSave: directoryForSavingButton.path, err := addToConversion(ConvertSetting{
OverwriteOutputFiles: isOverwriteOutputFiles, DirectoryForSave: directoryForSavingButton.path,
Format: selectEncoder.SelectFormat.Selected, OverwriteOutputFiles: isOverwriteOutputFiles,
Encoder: selectEncoder.Encoder, Format: selectEncoder.SelectFormat.Selected,
Encoder: selectEncoder.Encoder,
})
if err != nil {
formConvertor.conversionMessage.Text = err.Error()
}
fileForConversion.button.Enable()
directoryForSavingButton.button.Enable()
formConvertor.form.Enable()
}) })
if err != nil {
formConvertor.conversionMessage.Text = err.Error()
}
fileForConversion.button.Enable()
directoryForSavingButton.button.Enable()
formConvertor.form.Enable()
} }
return formConvertor return formConvertor

View File

@ -4,8 +4,12 @@ import (
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/lang"
"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/application/convertor" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
"image/color"
"strconv" "strconv"
"strings" "strings"
) )
@ -23,15 +27,17 @@ type queueLayout struct {
itemsContainer *fyne.Container itemsContainer *fyne.Container
queueAllStatistics QueueStatisticsAllContract queueAllStatistics QueueStatisticsAllContract
items map[int]queueLayoutItem items map[int]queueLayoutItem
ffmpegService ffmpeg.UtilitiesContract
} }
func NewQueueLayout() QueueLayoutContract { func NewQueueLayout(ffmpegService ffmpeg.UtilitiesContract) QueueLayoutContract {
items := map[int]queueLayoutItem{} items := map[int]queueLayoutItem{}
return &queueLayout{ return &queueLayout{
itemsContainer: container.NewVBox(), itemsContainer: container.NewVBox(),
queueAllStatistics: newQueueAllStatistics(&items), queueAllStatistics: newQueueAllStatistics(&items),
items: items, items: items,
ffmpegService: ffmpegService,
} }
} }
@ -43,16 +49,92 @@ func (l *queueLayout) GetQueueStatistics() QueueStatisticsAllContract {
return l.queueAllStatistics return l.queueAllStatistics
} }
func (l *queueLayout) AddQueue(key int, queue *convertor.Queue) { func (l *queueLayout) AddQueue(queueID int, queue *convertor.Queue) {
statusMessage := canvas.NewText(l.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
})
buttonPlay.Hide()
blockMessageError := container.NewHScroll(messageError)
blockMessageError.Hide()
content := container.NewVBox(
container.NewHScroll(widget.NewLabel(queue.Setting.FileInput.Name)),
container.NewHBox(
buttonPlay,
statusMessage,
),
blockMessageError,
container.NewPadded(),
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
container.NewPadded(),
)
l.addQueueStatistics() l.addQueueStatistics()
if l.GetQueueStatistics().IsChecked(queue.Status) == false {
content.Hide()
}
l.items[queueID] = queueLayoutItem{
CanvasObject: content,
StatusMessage: statusMessage,
BlockMessageError: blockMessageError,
MessageError: messageError,
buttonPlay: buttonPlay,
status: queue.Status,
}
l.itemsContainer.Add(content)
} }
func (l *queueLayout) ChangeQueue(key int, queue *convertor.Queue) { func (l *queueLayout) ChangeQueue(queueID int, queue *convertor.Queue) {
l.changeQueueStatistics(queue.Status) if item, ok := l.items[queueID]; ok {
statusColor := l.getStatusColor(queue.Status)
fyne.Do(func() {
item.StatusMessage.Text = l.getStatusTitle(queue.Status)
item.StatusMessage.Color = statusColor
item.StatusMessage.Refresh()
})
if queue.Error != nil {
fyne.Do(func() {
item.MessageError.Text = queue.Error.Error()
item.MessageError.Color = statusColor
item.BlockMessageError.Show()
item.MessageError.Refresh()
})
}
if queue.Status == convertor.StatusType(convertor.Completed) {
item.buttonPlay.Show()
item.buttonPlay.OnTapped = func() {
item.buttonPlay.Disable()
go func() {
ffplay, err := l.ffmpegService.GetFFplay()
if err == nil {
_ = ffplay.Play(&queue.Setting.FileOut)
}
fyne.Do(func() {
item.buttonPlay.Enable()
})
}()
}
}
if l.GetQueueStatistics().IsChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
item.CanvasObject.Hide()
} else if item.CanvasObject.Visible() == false {
item.CanvasObject.Show()
}
l.changeQueueStatistics(queue.Status)
}
} }
func (l *queueLayout) RemoveQueue(key int, status convertor.StatusContract) { func (l *queueLayout) RemoveQueue(queueID int, status convertor.StatusContract) {
l.removeQueueStatistics(status) if item, ok := l.items[queueID]; ok {
l.itemsContainer.Remove(item.CanvasObject)
l.removeQueueStatistics(status)
l.items[queueID] = queueLayoutItem{}
}
} }
func (l *queueLayout) addQueueStatistics() { func (l *queueLayout) addQueueStatistics() {
@ -104,12 +186,30 @@ func (l *queueLayout) removeQueueStatistics(status convertor.StatusContract) {
} }
} }
func (l *queueLayout) getStatusTitle(status convertor.StatusContract) string {
return lang.L(status.Name() + "Queue")
}
func (l *queueLayout) getStatusColor(status convertor.StatusContract) color.Color {
if status == convertor.StatusType(convertor.Error) {
return theme.Color(theme.ColorNameError)
}
if status == convertor.StatusType(convertor.Completed) {
return color.RGBA{R: 49, G: 127, B: 114, A: 255}
}
return theme.Color(theme.ColorNamePrimary)
}
type QueueStatisticsAllContract interface { type QueueStatisticsAllContract interface {
GetWaiting() QueueStatisticsContract GetWaiting() QueueStatisticsContract
GetInProgress() QueueStatisticsContract GetInProgress() QueueStatisticsContract
GetCompleted() QueueStatisticsContract GetCompleted() QueueStatisticsContract
GetError() QueueStatisticsContract GetError() QueueStatisticsContract
GetTotal() QueueStatisticsContract GetTotal() QueueStatisticsContract
IsChecked(status convertor.StatusContract) bool
} }
type queueAllStatistics struct { type queueAllStatistics struct {
@ -203,6 +303,23 @@ func (s *queueAllStatistics) GetTotal() QueueStatisticsContract {
return s.total return s.total
} }
func (s *queueAllStatistics) IsChecked(status convertor.StatusContract) bool {
if status == convertor.StatusType(convertor.InProgress) {
return s.inProgress.GetCheckbox().Checked
}
if status == convertor.StatusType(convertor.Completed) {
return s.completed.GetCheckbox().Checked
}
if status == convertor.StatusType(convertor.Error) {
return s.error.GetCheckbox().Checked
}
if status == convertor.StatusType(convertor.Waiting) {
return s.waiting.GetCheckbox().Checked
}
return true
}
func (s *queueAllStatistics) redrawingQueueItems(queueItems *map[int]queueLayoutItem) { func (s *queueAllStatistics) redrawingQueueItems(queueItems *map[int]queueLayoutItem) {
for _, item := range *queueItems { for _, item := range *queueItems {
if s.isChecked(item.status) == true && item.CanvasObject.Visible() == false { if s.isChecked(item.status) == true && item.CanvasObject.Visible() == false {