Skip to content
Open
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
2 changes: 1 addition & 1 deletion OpenUtau.Core/Classic/PluginRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static PluginRunner from(PathManager pathManager, DocManager docManager)

private static Action<ReplaceNoteEventArgs> ReplaceNoteMethod(DocManager docManager) {
return new Action<ReplaceNoteEventArgs>((args) => {
docManager.StartUndoGroup();
docManager.StartUndoGroup("command.batch.plugin");
docManager.ExecuteCmd(new RemoveNoteCommand(args.Part, args.ToRemove));
docManager.ExecuteCmd(new AddNoteCommand(args.Part, args.ToAdd));
docManager.EndUndoGroup();
Expand Down
66 changes: 65 additions & 1 deletion OpenUtau.Core/Commands/ExpCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public override ValidateOptions ValidateOptions
public ExpCommand(UVoicePart part) {
Part = part;
}
}
}

public class SetNoteExpressionCommand : ExpCommand {
static readonly HashSet<string> needsPhonemizer = new HashSet<string> {
Expand Down Expand Up @@ -396,6 +396,70 @@ public override void Unexecute() {
}
}

public class PasteCurveCommand : ExpCommand {
readonly UProject project;
readonly string abbr;
readonly int[] xs;
readonly int[] ys;
int[]? oldXs;
int[]? oldYs;
public PasteCurveCommand(UProject project, UVoicePart part, string abbr, IEnumerable<int> xs, IEnumerable<int> ys) : base(part) {
this.project = project;
this.abbr = abbr;
this.xs = xs.ToArray();
this.ys = ys.ToArray();
var curve = part.curves.FirstOrDefault(c => c.abbr == abbr);
oldXs = curve?.xs.ToArray();
oldYs = curve?.ys.ToArray();
}
public PasteCurveCommand(UProject project, UVoicePart part, string abbr, int startX, int startY, int endX, int endY) : base(part) {
this.project = project;
this.abbr = abbr;
this.xs = new int[] { startX, endX };
this.ys = new int[] { startY, endY };
var curve = part.curves.FirstOrDefault(c => c.abbr == abbr);
oldXs = curve?.xs.ToArray();
oldYs = curve?.ys.ToArray();
}
public override string ToString() => "Edit Curve";
public override void Execute() {
var curve = Part.curves.FirstOrDefault(c => c.abbr == abbr);
var track = project.tracks[Part.trackNo];
if (track.TryGetExpDescriptor(project, abbr, out var descriptor)) {
if (curve == null) {
curve = new UCurve(descriptor);
Part.curves.Add(curve);
}

var xs = this.xs.ToList();
var ys = this.ys.ToList();
xs.Insert(0, xs[0] - UCurve.interval);
ys.Insert(0, curve.Sample(xs[0]));
xs.Add(xs.Last() + UCurve.interval);
ys.Add(curve.Sample(xs.Last()));
ys = ys.Select(y => (int)Math.Clamp(y, descriptor.min, descriptor.max)).ToList();

curve.Set(xs.First(), ys.First(), xs.First(), ys.First());
curve.Set(xs.Last(), ys.Last(), xs.Last(), ys.Last());
for (int i = 0; i < xs.Count - 1; i++) {
curve.Set(xs[i + 1], ys[i + 1], xs[i], ys[i]);
}
}
}
public override void Unexecute() {
var curve = Part.curves.FirstOrDefault(c => c.abbr == abbr);
if (curve == null) {
return;
}
curve.xs.Clear();
curve.ys.Clear();
if (oldXs != null && oldYs != null) {
curve.xs.AddRange(oldXs);
curve.ys.AddRange(oldYs);
}
}
}

public class ClearCurveCommand : ExpCommand {
readonly string abbr;
readonly int[] oldXs;
Expand Down
4 changes: 3 additions & 1 deletion OpenUtau.Core/Commands/UCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ public abstract class UCommand {
}

public class UCommandGroup {
public string? NameKey;
public bool DeferValidate;
public List<UCommand> Commands;
public UCommandGroup(bool deferValidate) {
public UCommandGroup(string? nameKey, bool deferValidate) {
NameKey = nameKey;
DeferValidate = deferValidate;
Commands = new List<UCommand>();
}
Expand Down
28 changes: 24 additions & 4 deletions OpenUtau.Core/DocManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public class DocManager : SingletonBase<DocManager> {
public PhonemizerFactory[] PhonemizerFactories { get; private set; }
public UProject Project { get; private set; }
public bool HasOpenUndoGroup => undoGroup != null;
public List<UPart> PartsClipboard { get; set; }
public List<UNote> NotesClipboard { get; set; }
public List<UPart>? PartsClipboard { get; set; }
public List<UNote>? NotesClipboard { get; set; }
public CurveSelection? CurvesClipboard { get; set; }
internal PhonemizerRunner PhonemizerRunner { get; private set; }

public void Initialize(Thread mainThread, TaskScheduler mainScheduler) {
Expand Down Expand Up @@ -245,12 +246,12 @@ public void ExecuteCmd(UCommand cmd) {
}
}

public void StartUndoGroup(bool deferValidate = false) {
public void StartUndoGroup(string? nameKey = null, bool deferValidate = false) {
if (undoGroup != null) {
Log.Error("undoGroup already started");
EndUndoGroup();
}
undoGroup = new UCommandGroup(deferValidate);
undoGroup = new UCommandGroup(nameKey, deferValidate);
Log.Information("undoGroup started");
}

Expand Down Expand Up @@ -325,6 +326,25 @@ public void Redo() {
ExecuteCmd(new PreRenderNotification());
}

public bool GetUndoState(out string? key) {
key = null;
if (undoQueue.Count > 0) {
key = undoQueue.Last().NameKey;
return true;
} else {
return false;
}
}
public bool GetRedoState(out string? key) {
key = null;
if (redoQueue.Count > 0) {
key = redoQueue.Last().NameKey;
return true;
} else {
return false;
}
}

# endregion

# region Command Subscribers
Expand Down
6 changes: 3 additions & 3 deletions OpenUtau.Core/Editing/LyricBatchEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
return;
}
var lyrics = notes.Select(note => Transform(note.lyric)).ToArray();
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.lyric", true);
docManager.ExecuteCmd(new ChangeNoteLyricCommand(part, notes, lyrics));
docManager.EndUndoGroup();
}
Expand Down Expand Up @@ -130,7 +130,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
suffixes.Sort((a, b) => b.Length - a.Length);

// Set lyric and color
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.lyric", true);
foreach (var note in notes) {
foreach (var suffix in suffixes) {
if (note.lyric.Contains(suffix)) {
Expand Down Expand Up @@ -196,7 +196,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
}
var startPos = selectedNotes.First().position;
Queue<string> lyricsQueue = new Queue<string>();
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.lyric", true);
foreach(var note in part.notes.Where(n => n.position >= startPos)){
lyricsQueue.Enqueue(note.lyric);
if(selectedNotes.Contains(note)){
Expand Down
40 changes: 17 additions & 23 deletions OpenUtau.Core/Editing/NoteBatchEdits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (toAdd.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
foreach (var note in toAdd) {
note.lyric = lyric;
docManager.ExecuteCmd(new AddNoteCommand(part, note));
Expand Down Expand Up @@ -63,7 +63,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (toRemove.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
foreach (var note in toRemove) {
note.lyric = lyric;
docManager.ExecuteCmd(new RemoveNoteCommand(part, note));
Expand Down Expand Up @@ -108,7 +108,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (toAdd.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
foreach (var note in toAdd) {
note.lyric = lyric;
docManager.ExecuteCmd(new AddNoteCommand(part, note));
Expand All @@ -130,7 +130,7 @@ public Transpose(int deltaNoteNum, string name) {

public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, DocManager docManager) {
var notes = selectedNotes.Count > 0 ? selectedNotes : part.notes.ToList();
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
foreach (var note in notes) {
docManager.ExecuteCmd(new MoveNoteCommand(part, note, 0, deltaNoteNum));
}
Expand All @@ -151,7 +151,7 @@ public QuantizeNotes(int quantize) {

public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, DocManager docManager) {
var notes = selectedNotes.Count > 0 ? selectedNotes : part.notes.ToList();
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
foreach (var note in notes) {
int pos = note.position;
int end = note.End;
Expand Down Expand Up @@ -180,7 +180,7 @@ public AutoLegato() {
public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, DocManager docManager) {
var notes = selectedNotes.Count > 0 ? selectedNotes : part.notes.ToList();
notes.Sort((a, b) => a.position.CompareTo(b.position));
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
for (int i = 0; i < notes.Count - 1; i++) {
docManager.ExecuteCmd(new ResizeNoteCommand(part, notes[i], notes[i + 1].position - notes[i].position - notes[i].duration));
}
Expand All @@ -207,7 +207,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (notes.Count == 0) {
return;
}
docManager.StartUndoGroup();
docManager.StartUndoGroup("command.batch.note");
var currentNote = notes[0];
foreach (var note in notes.Skip(1)) {
if (note.position == currentNote.position) {
Expand Down Expand Up @@ -263,7 +263,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
}
int offset = left - minPosition - part.position;
notes.ForEach(note => note.position += offset);
DocManager.Inst.StartUndoGroup();
DocManager.Inst.StartUndoGroup("command.batch.note");
DocManager.Inst.ExecuteCmd(new AddNoteCommand(part, notes));
int minDurTick = part.GetMinDurTick(project);
if (part.Duration < minDurTick) {
Expand All @@ -284,7 +284,7 @@ public HanziToPinyin() {

public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, DocManager docManager) {
var pinyinResult = BaseChinesePhonemizer.Romanize(selectedNotes.Select(note => note.lyric));
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.lyric", true);
foreach (var t in Enumerable.Zip(selectedNotes, pinyinResult,
(note, pinyin) => Tuple.Create(note, pinyin))) {
docManager.ExecuteCmd(new ChangeNoteLyricCommand(part, t.Item1, t.Item2));
Expand All @@ -308,7 +308,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (notes.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
var track = project.tracks[part.trackNo];
foreach (var note in notes) {
foreach (UPhoneme phoneme in part.phonemes) {
Expand Down Expand Up @@ -351,7 +351,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (notes.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
const int maxTick = 20;
int delta;
Random random = new Random();
Expand Down Expand Up @@ -390,7 +390,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (notes.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
const int maxTick = 20 ;
Random random = new Random();
foreach (var note in notes) {
Expand Down Expand Up @@ -432,7 +432,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (notes.Count == 0) {
return;
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
Random random = new Random();
foreach (var note in notes) {
if (random.Next(2) == 0) { // +
Expand Down Expand Up @@ -527,7 +527,7 @@ public void RunAsync(
}

DocManager.Inst.PostOnUIThread(() => {
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
commands.ForEach(docManager.ExecuteCmd);
docManager.EndUndoGroup();
});
Expand Down Expand Up @@ -736,7 +736,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
pitch);
}
}
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
//Apply pitch points to notes
foreach (var note in notes) {
if (pitchPointsPerNote.TryGetValue(note.position, out var tickRangeAndPitch)) {
Expand All @@ -759,13 +759,7 @@ public void Run(UProject project, UVoicePart part, List<UNote> selectedNotes, Do
if (pitchPointsPerNote.TryGetValue(note.position, out var tickRangeAndPitch)) {
var start = tickRangeAndPitch.Item1 - part.position;
var end = tickRangeAndPitch.Item2 - part.position;
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
start, 0,
start, 0));
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
end, 0,
end, 0));
docManager.ExecuteCmd(new SetCurveCommand(project, part, Format.Ustx.PITD,
docManager.ExecuteCmd(new PasteCurveCommand(project, part, Format.Ustx.PITD,
start, 0,
end, 0));
}
Expand Down Expand Up @@ -856,7 +850,7 @@ public void RunAsync(
.ToList();

DocManager.Inst.PostOnUIThread(() => {
docManager.StartUndoGroup(true);
docManager.StartUndoGroup("command.batch.note", true);
commands.ForEach(docManager.ExecuteCmd);
docManager.EndUndoGroup();
});
Expand Down
Loading
Loading