Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,75 @@ public void MoveUp_TracksAbove_ReturnsSuccess()
_traceChangeManager.VerifySet(x => x.BulkEdit = false, Times.Once);
}

[TestMethod]
public void MoveUp_Move2Positions_ReturnsSuccess()
{
// Arrange
var track1End = new TimeSpan(0, 3, 12);
var track1 = new Track()
{
Position = 1,
Begin = TimeSpan.Zero,
End = track1End,
IsLinkedToPreviousTrack = true
};
var track2End = new TimeSpan(0, 7, 34);
var track2 = new Track()
{
Position = 2,
Begin = track1End,
End = track2End,
IsLinkedToPreviousTrack = true
};
var track3End = new TimeSpan(0, 10, 4);
var track3 = new Track()
{
Position = 3,
Begin = track2End,
End = track3End,
IsLinkedToPreviousTrack = true
};
var track4 = new Track()
{
Position = 4,
Begin = track3End,
End = new TimeSpan(0, 13, 45),
IsLinkedToPreviousTrack = true
};
var cuesheet = new Cuesheet()
{
Audiofiles = [
new() {
Tracks = [track4, track3, track2, track1]
}
],
};
track1.Cuesheet = cuesheet;
track2.Cuesheet = cuesheet;
track3.Cuesheet = cuesheet;
track4.Cuesheet = cuesheet;
track1.Audiofile = cuesheet.Audiofiles.First();
track2.Audiofile = cuesheet.Audiofiles.First();
track3.Audiofile = cuesheet.Audiofiles.First();
track4.Audiofile = cuesheet.Audiofiles.First();
_sessionStateContainer.Setup(x => x.ActiveCuesheet).Returns(cuesheet);
// Act
var result = _cuesheetManager.MoveUp([track2, track3], 2);
// Assert
Assert.IsTrue(result.IsSuccess);
Assert.AreEqual((ushort?)1, track2.Position);
Assert.AreEqual(TimeSpan.Zero, track2.Begin);
Assert.AreEqual(track1End, track2.End);
Assert.AreEqual((ushort?)2, track3.Position);
Assert.AreEqual(track1End, track3.Begin);
Assert.AreEqual(track2End, track3.End);
Assert.AreEqual((ushort?)3, track1.Position);
Assert.AreEqual(track2End, track1.Begin);
_traceChangeManager.Verify(x => x.AddChange(It.Is<TracedChange>(y => y.TraceableObject == cuesheet.Audiofiles.First() && y.TraceableChange.PropertyName == nameof(Audiofile.Tracks))), Times.Never);
_traceChangeManager.VerifySet(x => x.BulkEdit = true, Times.Once);
_traceChangeManager.VerifySet(x => x.BulkEdit = false, Times.Once);
}

[TestMethod]
public void MoveUp_NoTracksAbove_ReturnsFailure()
{
Expand Down Expand Up @@ -1060,6 +1129,78 @@ public void MoveDown_TracksBelow_ReturnsSuccess()
_traceChangeManager.VerifySet(x => x.BulkEdit = false, Times.Once);
}

[TestMethod]
public void MoveDown_Move2Positions_ReturnsSuccess()
{
// Arrange
var track1End = new TimeSpan(0, 3, 12);
var track1 = new Track()
{
Position = 1,
Begin = TimeSpan.Zero,
End = track1End,
IsLinkedToPreviousTrack = true
};
var track2End = new TimeSpan(0, 7, 34);
var track2 = new Track()
{
Position = 2,
Begin = track1End,
End = track2End,
IsLinkedToPreviousTrack = true
};
var track3End = new TimeSpan(0, 10, 4);
var track3 = new Track()
{
Position = 3,
Begin = track2End,
End = track3End,
IsLinkedToPreviousTrack = true
};
var track4 = new Track()
{
Position = 4,
Begin = track3End,
End = new TimeSpan(0, 13, 45),
IsLinkedToPreviousTrack = true
};
var cuesheet = new Cuesheet()
{
Audiofiles = [
new() {
Tracks = [track4, track3, track2, track1]
}
]
};
track1.Cuesheet = cuesheet;
track2.Cuesheet = cuesheet;
track3.Cuesheet = cuesheet;
track4.Cuesheet = cuesheet;
track1.Audiofile = cuesheet.Audiofiles.First();
track2.Audiofile = cuesheet.Audiofiles.First();
track3.Audiofile = cuesheet.Audiofiles.First();
track4.Audiofile = cuesheet.Audiofiles.First();
_sessionStateContainer.Setup(x => x.ActiveCuesheet).Returns(cuesheet);
// Act
var result = _cuesheetManager.MoveDown([track2, track1], 2);
// Assert
Assert.IsTrue(result.IsSuccess);
Assert.AreEqual((ushort?)1, track3.Position);
Assert.AreEqual(TimeSpan.Zero, track3.Begin);
Assert.AreEqual(track1End, track3.End);
Assert.AreEqual((ushort?)2, track4.Position);
Assert.AreEqual(track1End, track4.Begin);
Assert.AreEqual(track2End, track4.End);
Assert.AreEqual((ushort?)3, track1.Position);
Assert.AreEqual(track2End, track1.Begin);
Assert.AreEqual(track3End, track1.End);
Assert.AreEqual((ushort?)4, track2.Position);
Assert.AreEqual(track3End, track2.Begin);
_traceChangeManager.Verify(x => x.AddChange(It.Is<TracedChange>(y => y.TraceableObject == cuesheet.Audiofiles.First() && y.TraceableChange.PropertyName == nameof(Audiofile.Tracks))), Times.Never);
_traceChangeManager.VerifySet(x => x.BulkEdit = true, Times.Once);
_traceChangeManager.VerifySet(x => x.BulkEdit = false, Times.Once);
}

[TestMethod]
public void MoveDown_NoTracksBelow_ReturnsFailure()
{
Expand Down
35 changes: 35 additions & 0 deletions AudioCuesheetEditor.Tests/Services/UI/TraceChangeManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using AudioCuesheetEditor.Tests.Utility;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AudioCuesheetEditor.Tests.Services.UI
Expand Down Expand Up @@ -112,6 +113,40 @@ public void BulkEdit_AlreadyEnabledBulkEdit_DoesntDropPreviousEdits()
Assert.IsTrue(_traceChangeManager.CanRedo);
}


[TestMethod()]
public void BulkEditFalse_AfterBulkEditAndUndo_ResetsRedoStack()
{
// Arrange
var audiofile = new Audiofile();
var track1 = new Track();
var track2 = new Track();
var track3 = new Track();
_traceChangeManager.BulkEdit = true;
_traceChangeManager.AddChange(new(audiofile, new(new List<Track>() { track1 }, nameof(Audiofile.Tracks))));
track1.Audiofile = audiofile;
_traceChangeManager.BulkEdit = false;
_traceChangeManager.BulkEdit = true;
_traceChangeManager.AddChange(new(audiofile, new(new List<Track>() { track1, track2 }, nameof(Audiofile.Tracks))));
track1.Audiofile = audiofile;
track2.Audiofile = audiofile;
_traceChangeManager.BulkEdit = false;
_traceChangeManager.Undo();
_traceChangeManager.BulkEdit = true;
_traceChangeManager.AddChange(new(audiofile, new(new List<Track>() { track1, track2, track3 }, nameof(Audiofile.Tracks))));
track1.Audiofile = audiofile;
track2.Audiofile = audiofile;
track3.Audiofile = audiofile;
_traceChangeManager.BulkEdit = false;
_traceChangeManager.BulkEdit = true;
_traceChangeManager.AddChange(new(track2, new("Testartist", nameof(Track.Artist))));
// Act
_traceChangeManager.BulkEdit = false;
// Assert
Assert.IsTrue(_traceChangeManager.CanUndo);
Assert.IsFalse(_traceChangeManager.CanRedo);
}

[TestMethod()]
public void Undo_SingleChange_UndoesChange()
{
Expand Down
104 changes: 61 additions & 43 deletions AudioCuesheetEditor/Services/AudioCuesheet/CuesheetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,41 +141,50 @@ public bool IsMoveDownPossible(HashSet<Audiofile> selectedAudiofiles)
}

/// <inheritdoc/>
public Result MoveUp(HashSet<Track> selectedTracks)
public Result MoveUp(HashSet<Track> selectedTracks, uint positions = 1)
{
if (IsMoveUpPossible(selectedTracks) == false)
{
return Result.Failure(new Error(ErrorType.NotPossible, "Moving tracks up is not possible!"));
}
_traceChangeManager.BulkEdit = true;
var cuesheet = _sessionStateContainer.ActiveCuesheet;
foreach (var selectedTrack in selectedTracks.OrderBy(x => x.Position))
while (positions > 0)
{
var previousTrack = cuesheet?.Audiofiles.SelectMany(x => x.Tracks).FirstOrDefault(x => x.Position == selectedTrack.Position - 1);
if (previousTrack?.Audiofile != null && previousTrack.Audiofile != selectedTrack.Audiofile)
if (IsMoveUpPossible(selectedTracks) == false)
{
SwitchAudiofile(selectedTrack, previousTrack.Audiofile);
positions = 0;
break;
}
else
var cuesheet = _sessionStateContainer.ActiveCuesheet;
foreach (var selectedTrack in selectedTracks.OrderBy(x => x.Position))
{
var newBegin = previousTrack?.Begin;
var newEnd = previousTrack?.End;
if (previousTrack != null)
var previousTrack = cuesheet?.Audiofiles.SelectMany(x => x.Tracks).FirstOrDefault(x => x.Position == selectedTrack.Position - 1);
if (previousTrack?.Audiofile != null && previousTrack.Audiofile != selectedTrack.Audiofile)
{
SwitchAudiofile(selectedTrack, previousTrack.Audiofile);
}
else
{
_trackManager.SetProperty(previousTrack, x => x.Position, selectedTrack.Position);
_trackManager.SetProperty(previousTrack, x => x.Begin, selectedTrack.Begin);
_trackManager.SetProperty(previousTrack, x => x.End, selectedTrack.End);
var newBegin = previousTrack?.Begin;
var newEnd = previousTrack?.End;
if (previousTrack != null)
{
_trackManager.SetProperty(previousTrack, x => x.Position, selectedTrack.Position);
_trackManager.SetProperty(previousTrack, x => x.Begin, selectedTrack.Begin);
_trackManager.SetProperty(previousTrack, x => x.End, selectedTrack.End);
}
_trackManager.SetProperty(selectedTrack, x => x.Position, (ushort?)(selectedTrack.Position - 1));
_trackManager.SetProperty(selectedTrack, x => x.Begin, newBegin);
_trackManager.SetProperty(selectedTrack, x => x.End, newEnd);
}
_trackManager.SetProperty(selectedTrack, x => x.Position, (ushort?)(selectedTrack.Position - 1));
_trackManager.SetProperty(selectedTrack, x => x.Begin, newBegin);
_trackManager.SetProperty(selectedTrack, x => x.End, newEnd);

}

}
foreach (var audiofile in cuesheet!.Audiofiles)
{
var orderedTracks = audiofile.Tracks.OrderBy(x => x.Position).ToList();
_audiofileManager.SetProperty(audiofile, x => x.Tracks, orderedTracks);
foreach (var audiofile in cuesheet!.Audiofiles)
{
var orderedTracks = audiofile.Tracks.OrderBy(x => x.Position).ToList();
_audiofileManager.SetProperty(audiofile, x => x.Tracks, orderedTracks);
}
positions--;
}
_traceChangeManager.BulkEdit = false;
return Result.Success();
Expand Down Expand Up @@ -216,40 +225,49 @@ public Result MoveUp(HashSet<Audiofile> selectedAudiofiles)
}

/// <inheritdoc/>
public Result MoveDown(HashSet<Track> selectedTracks)
public Result MoveDown(HashSet<Track> selectedTracks, uint positions = 1)
{
if (IsMoveDownPossible(selectedTracks) == false)
{
return Result.Failure(new Error(ErrorType.NotPossible, "Moving tracks down is not possible!"));
}
_traceChangeManager.BulkEdit = true;
var cuesheet = _sessionStateContainer.ActiveCuesheet;
foreach (var selectedTrack in selectedTracks.OrderByDescending(x => x.Position))
while (positions > 0)
{
var nextTrack = cuesheet?.Audiofiles.SelectMany(x => x.Tracks).FirstOrDefault(x => x.Position == selectedTrack.Position + 1);
if (nextTrack?.Audiofile != null && nextTrack.Audiofile != selectedTrack.Audiofile)
if (IsMoveDownPossible(selectedTracks) == false)
{
SwitchAudiofile(selectedTrack, nextTrack.Audiofile);
positions = 0;
break;
}
else
var cuesheet = _sessionStateContainer.ActiveCuesheet;
foreach (var selectedTrack in selectedTracks.OrderByDescending(x => x.Position))
{
var newBegin = nextTrack?.Begin;
var newEnd = nextTrack?.End;
if (nextTrack != null)
var nextTrack = cuesheet?.Audiofiles.SelectMany(x => x.Tracks).FirstOrDefault(x => x.Position == selectedTrack.Position + 1);
if (nextTrack?.Audiofile != null && nextTrack.Audiofile != selectedTrack.Audiofile)
{
SwitchAudiofile(selectedTrack, nextTrack.Audiofile);
}
else
{
_trackManager.SetProperty(nextTrack, x => x.Position, selectedTrack.Position);
_trackManager.SetProperty(nextTrack, x => x.Begin, selectedTrack.Begin);
_trackManager.SetProperty(nextTrack, x => x.End, selectedTrack.End);
var newBegin = nextTrack?.Begin;
var newEnd = nextTrack?.End;
if (nextTrack != null)
{
_trackManager.SetProperty(nextTrack, x => x.Position, selectedTrack.Position);
_trackManager.SetProperty(nextTrack, x => x.Begin, selectedTrack.Begin);
_trackManager.SetProperty(nextTrack, x => x.End, selectedTrack.End);
}
_trackManager.SetProperty(selectedTrack, x => x.Position, (ushort?)(selectedTrack.Position + 1));
_trackManager.SetProperty(selectedTrack, x => x.Begin, newBegin);
_trackManager.SetProperty(selectedTrack, x => x.End, newEnd);
}
_trackManager.SetProperty(selectedTrack, x => x.Position, (ushort?)(selectedTrack.Position + 1));
_trackManager.SetProperty(selectedTrack, x => x.Begin, newBegin);
_trackManager.SetProperty(selectedTrack, x => x.End, newEnd);
}
}
foreach (var audiofile in cuesheet!.Audiofiles)
{
var orderedTracks = audiofile.Tracks.OrderBy(x => x.Position).ToList();
_audiofileManager.SetProperty(audiofile, x => x.Tracks, orderedTracks);
foreach (var audiofile in cuesheet!.Audiofiles)
{
var orderedTracks = audiofile.Tracks.OrderBy(x => x.Position).ToList();
_audiofileManager.SetProperty(audiofile, x => x.Tracks, orderedTracks);
}
positions--;
}
_traceChangeManager.BulkEdit = false;
return Result.Success();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ public interface ICuesheetManager
/// Moves selected tracks up
/// </summary>
/// <param name="selectedTracks"></param>
Result MoveUp(HashSet<Track> selectedTracks);
/// <param name="positions"></param>
/// <returns></returns>
Result MoveUp(HashSet<Track> selectedTracks, uint positions = 1);
/// <summary>
/// Moves selected audiofiles up
/// </summary>
Expand All @@ -89,8 +91,9 @@ public interface ICuesheetManager
/// Moves selected tracks down
/// </summary>
/// <param name="selectedTracks"></param>
/// <param name="positions"></param>
/// <returns></returns>
Result MoveDown(HashSet<Track> selectedTracks);
Result MoveDown(HashSet<Track> selectedTracks, uint positions = 1);
/// <summary>
/// Moves selected audiofiles down
/// </summary>
Expand Down
6 changes: 5 additions & 1 deletion AudioCuesheetEditor/Services/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ public enum ErrorType
/// <summary>
/// Current action is not possible
/// </summary>
NotPossible
NotPossible,
/// <summary>
/// Action was aborted
/// </summary>
Aborted,
}

/// <summary>
Expand Down
Loading
Loading