diff --git a/cmd/sandboxer/submissions.go b/cmd/sandboxer/submissions.go index 2b9a0d6..cf58dc2 100644 --- a/cmd/sandboxer/submissions.go +++ b/cmd/sandboxer/submissions.go @@ -271,27 +271,56 @@ func (s *SubmissionsWindow) PopUpMenu(tsk *task.Task) *fyne.Menu { recheckItem.Icon = theme.SearchReplaceIcon() //recheckItem.Disabled = (tsk.RiskLevel != sandbox.RiskLevelError) && (tsk.RiskLevel != sandbox.RiskLevelUnsupported) - deleteTaskItem := fyne.NewMenuItem("Delete Task", func() { + deleteTaskItem := fyne.NewMenuItem("This Task", func() { s.DeleteTask(tsk) }) - deleteTaskItem.Icon = theme.CancelIcon() + deleteSameTasksItem := fyne.NewMenuItem("Same Tasks", func() { + s.DeleteSameTasks(tsk) + }) + deleteAllTasksItem := fyne.NewMenuItem("All Tasks", func() { + s.DeleteAllTasks() + }) + deleteItem := fyne.NewMenuItem("Delete", nil) + deleteItem.Icon = theme.CancelIcon() + deleteItem.ChildMenu = fyne.NewMenu(globals.AppName, + deleteTaskItem, + deleteSameTasksItem, + deleteAllTasksItem, + ) + return fyne.NewMenu(globals.AppName, reportItem, investigationItem, recheckItem, - deleteTaskItem, + deleteItem, deleteFileItem) } func (s *SubmissionsWindow) DeleteTask(tsk *task.Task) { - err := tsk.Delete() + err := s.list.DeleteTask(tsk) + if err != nil { + dialog.ShowError(err, s.win) + logging.LogError(err) + return + } +} + +func (s *SubmissionsWindow) DeleteSameTasks(tsk *task.Task) { + err := s.list.DeleteSameTasks(tsk) + if err != nil { + dialog.ShowError(err, s.win) + logging.LogError(err) + return + } +} + +func (s *SubmissionsWindow) DeleteAllTasks() { + err := s.list.DeleteAllTasks() if err != nil { dialog.ShowError(err, s.win) logging.LogError(err) return } - s.list.DelByID(tsk.Number) - //s.PopulateOnScreenTasks() } func (s *SubmissionsWindow) RunOpen(path string) { diff --git a/pkg/dispatchers/launcher.go b/pkg/dispatchers/launcher.go index 558abfe..18cc22c 100644 --- a/pkg/dispatchers/launcher.go +++ b/pkg/dispatchers/launcher.go @@ -73,7 +73,7 @@ func (l *Launcher) LoadTasks() { logging.LogError(err) return } - logging.Debugf("LoadTasks %d", len(l.list.Tasks)) + //logging.Debugf("LoadTasks %d", len(l.list.Tasks)) l.list.Process(func(ids []task.ID) { for _, id := range ids { err := l.list.Task(id, func(tsk *task.Task) error { diff --git a/pkg/task/list.go b/pkg/task/list.go index 31a3204..7434afa 100644 --- a/pkg/task/list.go +++ b/pkg/task/list.go @@ -25,16 +25,18 @@ type TaskListInterface interface { NewTask(path string) ID } +//type TasksMap Map[ID, *Task] + type TaskList struct { mx sync.RWMutex changed chan struct{} - Tasks map[ID]*Task + Tasks *Map[ID, *Task] TasksCount ID } func NewList() *TaskList { l := &TaskList{ - Tasks: make(map[ID]*Task), + Tasks: new(Map[ID, *Task]), changed: make(chan struct{}, 1000), } l.changed <- struct{}{} @@ -50,7 +52,7 @@ func (l *TaskList) Updated() { } func (l *TaskList) Length() int { - return len(l.Tasks) + return l.Tasks.Length() } func (l *TaskList) Changes() chan struct{} { @@ -69,39 +71,45 @@ func (l *TaskList) NewTask(taskType TaskType, path string) (ID, error) { } logging.Debugf("NewTask %d, %s", l.TasksCount, path) tsk = NewTask(l.TasksCount, taskType, path) - l.Tasks[tsk.Number] = tsk + //l.Tasks[tsk.Number] = tsk + l.Tasks.Store(tsk.Number, tsk) l.Updated() l.TasksCount++ return tsk.Number, nil } -func (l *TaskList) FindTask(path string) *Task { +func (l *TaskList) FindTask(path string) (result *Task) { // More sophisticated paths comparison algoritm could be used or // os.SameFile function - for _, tsk := range l.Tasks { + l.Tasks.Range(func(id ID, tsk *Task) bool { if path == tsk.Path { - return tsk + result = tsk + return false } - } - return nil + return true + }) + return } func (l *TaskList) DelByID(id ID) { - defer l.lockUnlock()() //mx.Lock() - logging.Debugf("DelByID, id = %d, len = %d", id, len(l.Tasks)) - delete(l.Tasks, id) + //defer l.lockUnlock()() //mx.Lock() + //logging.Debugf("DelByID, id = %d, len = %d", id, len(l.Tasks)) + l.Tasks.Delete(id) l.Updated() } func (l *TaskList) Get(num ID) *Task { - defer l.lockUnlock()() - return l.Tasks[num] + // + // It was here: + //defer l.lockUnlock()() + tsk, _ := l.Tasks.Load(num) + return tsk } func (l *TaskList) Task(num ID, callback func(tsk *Task) error) error { //defer l.lockUnlock()() - tsk := l.Tasks[num] - if tsk == nil { + tsk, ok := l.Tasks.Load(num) + if !ok { return fmt.Errorf("missing task #%d", num) } //defer tsk.lockUnlock()() @@ -118,39 +126,56 @@ func (l *TaskList) unlock() { l.mx.Unlock() } -func (l *TaskList) GetIDs() []ID { - keys := make([]ID, len(l.Tasks)) - i := 0 - for k := range l.Tasks { - keys[i] = k - i++ - } - return keys +func (l *TaskList) GetIDs() (keys []ID) { + l.Tasks.Range(func(id ID, _ *Task) bool { + keys = append(keys, id) + return true + }) + return } func (l *TaskList) Process(callback func([]ID)) { - defer l.lockUnlock()() + //defer l.lockUnlock()() keys := l.GetIDs() sort.Slice(keys, func(i, j int) bool { - return l.Tasks[keys[i]].SubmitTime.After(l.Tasks[keys[j]].SubmitTime) + a, ok := l.Tasks.Load(keys[i]) + if !ok { + return false + } + b, ok := l.Tasks.Load(keys[j]) + if !ok { + return false + } + return a.SubmitTime.After(b.SubmitTime) }) callback(keys) } -func (l *TaskList) SortTasks() { - defer l.lockUnlock()() - keys := l.GetIDs() - sort.Slice(keys, func(i, j int) bool { - return l.Tasks[keys[i]].SubmitTime.After(l.Tasks[keys[j]].SubmitTime) - }) -} +/* + func (l *TaskList) SortTasks() { + defer l.lockUnlock()() + keys := l.GetIDs() + sort.Slice(keys, func(i, j int) bool { + a, ok := l.Tasks.Load(keys[i]) + if !ok { + return false + } + b, ok := l.Tasks.Load(keys[j]) + if !ok { + return false + } + return a.SubmitTime.After(b.SubmitTime) + }) + } +*/ func (l *TaskList) CountActiveTasks() (count int) { - for _, t := range l.Tasks { - if t.Channel != ChDone { + l.Tasks.Range(func(id ID, tsk *Task) bool { + if tsk.Channel != ChDone { count++ } - } + return true + }) return } @@ -181,7 +206,7 @@ func (l *TaskList) LoadTasks(keepDays int) error { } tsk.Number = l.TasksCount l.TasksCount++ - l.Tasks[tsk.Number] = tsk + l.Tasks.Store(tsk.Number, tsk) } return nil } @@ -195,3 +220,42 @@ func (l *TaskList) Save(filePath string) error { return os.WriteFile(filePath, data, 0644) } */ + +func (l *TaskList) DeleteTask(tsk *Task) error { + err := tsk.Delete() + if err != nil { + return err + } + l.DelByID(tsk.Number) + return nil +} + +func (l *TaskList) DeleteSameTasks(tsk *Task) (err error) { + l.Tasks.Range(func(id ID, t *Task) bool { + if t.Channel != tsk.Channel { + return true + } + if t.RiskLevel != tsk.RiskLevel { + return true + } + err = t.Delete() + if err != nil { + return false + } + l.DelByID(t.Number) + return true + }) + return +} + +func (l *TaskList) DeleteAllTasks() (err error) { + l.Tasks.Range(func(id ID, t *Task) bool { + err = t.Delete() + if err != nil { + return false + } + l.DelByID(t.Number) + return true + }) + return +}