public static Note Clone(Guid parentId, Chord chord, Repository.DataService.Measure measure, int x, int y, Note source, Collaborator collaborator) { Note obj = null; try { obj = Create(chord, measure, x, y); obj.Accidental_Id = source.Accidental_Id; obj.Duration = source.Duration; obj.Instrument_Id = source.Instrument_Id; obj.Chord_Id = parentId; obj.IsDotted = source.IsDotted; obj.IsSpanned = source.IsSpanned; obj.Location_X = source.Location_X; obj.Location_Y = source.Location_Y; obj.Key_Id = source.Key_Id; obj.Orientation = source.Orientation; obj.Slot = source.Slot; obj.Pitch = source.Pitch; obj.Type = source.Type; obj.Vector_Id = source.Vector_Id; obj.StartTime = source.StartTime; obj.Status = source.Status; obj.Audit = GetAudit(); Cache.Notes.Add(obj); } catch (Exception ex) { Exceptions.HandleException(ex); } return obj; }
public ChordViewModel(string id) { _chord = null; HideSelector(); Chord = (from obj in Cache.Chords where obj.Id == Guid.Parse(id) select obj).First(); if (!EditorState.IsComposing) { EA.GetEvent<EditorStateChanged>().Publish(true); } DefineCommands(); SubscribeEvents(); EA.GetEvent<NotifyChord>().Publish(Chord.Measure_Id); EA.GetEvent<AdjustMeasureEndSpace>().Publish(string.Empty); }
public static Note Create(Chord chord, Repository.DataService.Measure measure, int x, int _clickY) { //TODO: x parameter appears to be unused. Repository.DataService.Note note = null; try { if (EditorState.IsPasting) { _clickY = _clickY + Measure.NoteHeight; } var _acc = ""; var clickY = _clickY; // locationY is the raw click Y coordinate adjustedY = _clickY; // Location_Y is the adjusted Y coordinate. note = Repository.Create<Note>(); note.Type = (short)(EditorState.IsRest() ? 1 : 0); note.Id = Guid.NewGuid(); note.Status = CollaborationManager.GetBaseStatus(); note.StartTime = chord.StartTime; if (EditorState.Duration != null) note.Duration = (decimal)EditorState.Duration; if (EditorState.IsNoteSelected()) { note.Key_Id = Keys.Key.Id; note.Instrument_Id = measure.Instrument_Id; note.IsDotted = EditorState.Dotted; //TODO: having both adjustedY and clickY is redundant. At one time we needed to preserve the original clickY, but not anymore. if (Slot.Normalize_Y.ContainsKey(clickY)) adjustedY = Slot.Normalize_Y[clickY]; var slotInfo = Slot.Slot_Y[adjustedY].Split(','); adjustedY += Finetune.Slot.Correction_Y; var pitchBase = slotInfo[1]; if (!string.IsNullOrEmpty(EditorState.Accidental)) { _acc = (from a in Accidentals.AccidentalList where a.Caption == EditorState.Accidental select a.Name).First(); } note.Accidental_Id = null; var acc = GetAccidentalSymbol(_acc, pitchBase); if (acc.Length > 0) note.Accidental_Id = (from a in Accidentals.AccidentalList where a.Name == acc select a.Id).First(); var slot = slotInfo[0]; if (string.Format("{0}{1}", pitchBase, acc) == "Cb") slot = (int.Parse(slot) - 4).ToString(CultureInfo.InvariantCulture); else if (string.Format("{0}{1}", pitchBase, acc) == "Bs") { slot = (int.Parse(slot) + 4).ToString(CultureInfo.InvariantCulture); } note.Slot = slot; note.Octave_Id = short.Parse(slot.ToCharArray()[0].ToString(CultureInfo.InvariantCulture)); note.Pitch = string.Format("{0}{1}{2}", pitchBase, note.Octave_Id, acc); note.Orientation = (Slot.OrientationMap.ContainsKey(note.Slot)) ? (short)Slot.OrientationMap[note.Slot] : (short)_Enum.Orientation.Up; adjustedY = adjustedY - Measure.NoteHeight; note.Location_Y = adjustedY; } else { note.Key_Id = Keys.Key.Id; note.Instrument_Id = null; note.IsDotted = EditorState.Dotted; note.Orientation = (int)_Enum.Orientation.Rest; note.Pitch = Defaults.RestSymbol; note.Location_Y = Finetune.Measure.RestLocation_Y; } note.Vector_Id = (short)EditorState.VectorId; note.Audit = GetAudit(); note.Chord_Id = chord.Id; } catch (Exception ex) { Exceptions.HandleException(ex); } return note; }
public static Note Create(Chord chord, Repository.DataService.Measure measure, int x) { return Create(chord, measure, x, 0); }
private bool ContainsStatus(Chord chord, _Enum.Status status) { return chord.Notes.Any(note => ContainsStatus(note, status)); }
private void AcceptDeletion(int limboStatus, int deletedStatus, short acceptedStatus, Chord chord) { //either the author is accepting a contributor deletion, or a contributor is accepting a author deletion. either way, //the note is forever gone for both contributor and author. Note: Contributor status is set to Purged here, and //Author status is set to Purged at the end of this method. Note.Status = Collaborations.SetStatus(Note, (int)_Enum.Status.Purged); //is there a rest out there that may need to become visible? var n = (from a in Cache.Notes where Collaborations.GetStatus(a) == limboStatus && // only rests can have a Limbo status a.StartTime == Note.StartTime select a); var e = n as List<Note> ?? n.ToList(); if (e.Any()) { var rest = e.SingleOrDefault(); if (rest != null) { //yes, there is a rest, but first check if there are other deleted notes pending accept/reject in this chord? var m = (from a in Cache.Notes where Collaborations.GetStatus(a) == deletedStatus && a.StartTime == Note.StartTime select a); if (!m.Any() && !CollaborationManager.IsActive(chord)) { //rest.Location_Y = Finetune.Measure.RestLocation_Y; rest.Status = Collaborations.SetStatus(rest, acceptedStatus); //again rest.Status = Collaborations.SetAuthorStatus(rest, (int)_Enum.Status.AuthorOriginal); } } } Note.Status = Collaborations.SetAuthorStatus(Note, (int)_Enum.Status.Purged); }
public void OnDelete(Chord chord) { if (chord.Id != Chord.Id) return; SetChordContext(); ChordManager.Delete(chord); }
public static Chord Clone(Repository.DataService.Measure measure, Chord source, Collaborator collaborator) { Chord obj; Measure = measure; EditorState.Duration = (double)source.Duration; obj = GetOrCreate(measure.Id, (decimal)source.StartTime); obj.Id = Guid.NewGuid(); obj.Measure_Id = measure.Id; obj.Duration = source.Duration; obj.Key_Id = source.Key_Id; obj.Location_X = source.Location_X; obj.Location_Y = source.Location_Y; obj.Audit = GetAudit(); obj.StartTime = source.StartTime; obj.Status = CollaborationManager.GetBaseStatus(); var index = 0; foreach (Note note in source.Notes) { Note n = NoteController.Clone(obj.Id, source, Measure, obj.Location_X + (index * 16), note.Location_Y, note, collaborator); obj.Notes.Add(n); index++; } Cache.Chords.Add(obj); InertChords.Add(obj.Id); return obj; }
public static Notegroup ParseChord(Chord chord, Note note) { Notegroup noteGroup = null; try { foreach (var n in chord.Notes.Where(_note => CollaborationManager.IsActive(_note)).Where(_note => _note.Duration == note.Duration)) { if (noteGroup == null) { if (chord.StartTime != null && n.Orientation != null) { noteGroup = new Notegroup(n.Duration, (Double)chord.StartTime, (short)n.Orientation) { IsRest = n.Pitch.Trim().ToUpper() == Infrastructure.Constants.Defaults.RestSymbol }; noteGroup.Notes.Add(n); } } else { noteGroup.Notes.Add(n); } } } catch (Exception ex) { Exceptions.HandleException(ex); } return noteGroup; }
private static int GetChordXCoordinate(_Enum.NotePlacementMode notePlacementType, Chord chord) { var locationX = 0; var proportionalSpace = DurationManager.GetProportionalSpace(); var spacing = ((Preferences.SpacingMode == _Enum.MeasureSpacingMode.Constant) ? Measure.Spacing : proportionalSpace); MeasureChordNotegroups = NotegroupManager.ParseMeasure(out ChordStartTimes, out ChordInactiveTimes); var chords = GetActiveChords(Measure.Chords); switch (notePlacementType) { case _Enum.NotePlacementMode.Insert: if (_chord1 != null && _chord2 != null) { locationX = _chord1.Location_X + spacing; chord.Location_X = locationX; chord.StartTime = _chord2.StartTime; foreach (Chord c in chords) //no need to filter measure.chords using GetActiveChords(). { if (c.Location_X > _chord1.Location_X && chord != c) { c.Location_X += spacing; if (c.StartTime != null) c.StartTime = (double)c.StartTime + (double)chord.Duration; _r.Update(c); } _ea.GetEvent<SynchronizeChord>().Publish(c); _ea.GetEvent<UpdateChord>().Publish(c); } } break; case _Enum.NotePlacementMode.Append: var a = (from c in chords where c.StartTime < Chord.StartTime select c.Location_X); var e = a as List<int> ?? a.ToList(); locationX = (!e.Any()) ? Infrastructure.Constants.Measure.Padding : Convert.ToInt32(e.Max()) + spacing; break; } return locationX; }
public static decimal SetDuration(Chord chord) { var n = GetActiveNotes(chord.Notes); var a = (from c in n select c.Duration); var e = a as List<decimal> ?? a.ToList(); return (!e.Any()) ? chord.Duration : e.Min(); }
public static void OnSynchronize(Chord chord) { //when the startTime or location of a chord changes, then it's constituent notes must be synchronized with the chord. ObservableCollection<Note> notes = GetActiveNotes(chord.Notes); foreach (var note in notes) { if (note.StartTime != chord.StartTime || note.Location_X != chord.Location_X) { note.StartTime = chord.StartTime; note.Location_X = chord.Location_X; _ea.GetEvent<UpdateChord>().Publish(chord); _ea.GetEvent<UpdateNote>().Publish(note); _r.Update(note); } } }
public static _Enum.NotePlacementMode GetNotePlacementMode(out Chord leftChord, out Chord rightChord) { leftChord = null; rightChord = null; var clickX = Location_X + Finetune.Measure.ClickNormalizer_X; var mode = GetBracketChords(out leftChord, out rightChord, clickX); return mode; }
public static _Enum.NotePlacementMode GetBracketChords(out Chord leftChord, out Chord rightChord, int clickX) { leftChord = null; rightChord = null; var leftX = Defaults.MinusInfinity; var rightX = Defaults.PlusInfinity; var notePlacementMode = _Enum.NotePlacementMode.Append; var chords = GetActiveChords(Measure.Chords); if (!chords.Any()) return notePlacementMode; leftChord = chords[0]; MeasureChordNotegroups = NotegroupManager.ParseMeasure(out ChordStartTimes, out ChordInactiveTimes); for (var i = 0; i < chords.Count - 1; i++) { var ch1 = chords[i]; var ch2 = chords[i + 1]; if (clickX > ch1.Location_X && clickX < ch2.Location_X) { leftChord = ch1; rightChord = ch2; notePlacementMode = _Enum.NotePlacementMode.Insert; } if (clickX > ch1.Location_X && ch1.Location_X > leftX) { leftChord = ch1; leftX = ch1.Location_X; } if (clickX < ch2.Location_X && ch2.Location_X < rightX) { rightChord = ch2; rightX = ch2.Location_X; } } return notePlacementMode; }
public static void Delete(Chord chord) { //the only way a chord can be deleted is by deleting all of it's notes first. so, every time a note is deleted, this method //is called to check and see if the underlying parent chord should be deleted. if so, it is pseudo-deleted by adding a rest to the chord husk. Repository.DataService.Measure measure = (from a in Cache.Measures where a.Id == ViewModel.Chord.Measure_Id select a).First(); Note rest; if (!EditorState.IsCollaboration) { //if we are deleting the last note (or the only rest) in the chord, and the composition is not under collaboration //then delete the chord from the DB and insert a rest in it's place. if (ViewModel.Chord.Notes.Count == 0) { //add a rest to the empty chord EditorState.Duration = (double)chord.Duration; EditorState.SetRestContext(); rest = NoteController.Create(chord, measure, chord.Location_X); rest.Pitch = Defaults.RestSymbol; rest.Location_X = chord.Location_X; Cache.Notes.Add(rest); chord.Notes.Add(rest); _r.Update(chord); } } else { //if isCollaboration, and all notes in the chord are inactive, then start the //flow that replaces the chord with a rest. if (!CollaborationManager.IsActive(chord)) { EditorState.Duration = (double)chord.Duration; EditorState.SetRestContext(); rest = NoteController.Create(chord, measure, chord.Location_X); rest.Pitch = Defaults.RestSymbol; rest.Location_X = chord.Location_X; //the note is already deleted marked as purged. we just need to determine the appropriate status for the rest. //if the deleted note was purgeable (see NoteController) then it was deleted from the DB and the rest status //is set as if it was a normal add to the measure. if (EditorState.Purgable) { if (EditorState.EditContext == (int)_Enum.EditContext.Authoring) { rest.Status = Collaborations.SetStatus(rest, (int)_Enum.Status.AuthorAdded); rest.Status = Collaborations.SetAuthorStatus(rest, (int)_Enum.Status.AuthorOriginal); } else { rest.Status = Collaborations.SetStatus(rest, (int)_Enum.Status.ContributorAdded, Collaborations.Index); rest.Status = Collaborations.SetAuthorStatus(rest, (int)_Enum.Status.PendingAuthorAction); } EditorState.Purgable = false; } else { //if note was not purgeable (see NoteController) it must be retained with it's status marked WaitingOn.... //the actual status won't be resolved until the note author chooses to reject or accept the note deletion. //another way to say it: the loged in user deleted this note. it's the last note in the chord so the chord is //replaced by a rest but we can't delete the note because the other collaborator may not want to accept //the delete. so there is a rest and a chord occupying the same starttime. if the collaborator accepts //the delete, the note can be purged and the rest has its status set appropriately. if the delete is //rejected, both remain at the same starttime and the rest has its staus set appropriately (see NoteViewModel.OnRejectChange) rest.Status = (EditorState.EditContext == (int)_Enum.EditContext.Authoring) ? Collaborations.SetStatus(rest, (short)_Enum.Status.WaitingOnContributor, 0) : Collaborations.SetStatus(rest, (short)_Enum.Status.WaitingOnAuthor, Collaborations.Index); //replaced a hard coded '0' with 'Collaborations.Index' on 9/27/2012 } Cache.Notes.Add(rest); chord.Notes.Add(rest); _r.Update(chord); } } _ea.GetEvent<DeleteTrailingRests>().Publish(measure.Id); var chords = GetActiveChords(measure.Chords); if (chords.Count > 0) { _ea.GetEvent<UpdateSpanManager>().Publish(measure.Id); MeasureChordNotegroups = NotegroupManager.ParseMeasure(out ChordStartTimes, out ChordInactiveTimes); _ea.GetEvent<SpanMeasure>().Publish(measure); } }
public static Chord Clone(Repository.DataService.Measure measure, Chord source) { Chord obj = null; try { Measure = measure; EditorState.Duration = (double)source.Duration; if (source.StartTime != null) { obj = GetOrCreate(measure.Id, (decimal) source.StartTime); obj.Id = Guid.NewGuid(); obj.Measure_Id = measure.Id; obj.Duration = source.Duration; obj.Key_Id = source.Key_Id; obj.Location_X = source.Location_X; obj.Location_Y = source.Location_Y; obj.Audit = GetAudit(); obj.StartTime = source.StartTime; obj.Status = CollaborationManager.GetBaseStatus(); int index = 0; foreach (var note in source.Notes) { var clonedNote = NoteController.Clone(obj.Id, source, Measure, obj.Location_X + (index*16), note.Location_Y, note); obj.Notes.Add(clonedNote); index++; } Cache.Chords.Add(obj); } } catch (Exception ex) { Exceptions.HandleException(ex); } return obj; }
public static bool IsActive(Chord ch) { bool result = false; try { var a = (from n in ch.Notes where (IsActionable(n, null)) select n); result = a.Any(); } catch (Exception ex) { Exceptions.HandleException(ex, "class = CollaborationManager method = IsActive(Repository.DataService.Chord ch)"); } return result; }
public void OnUpdateChord(Chord chord) { if (chord.Id != Chord.Id) return; Chord = chord; }
private static Notegroup CreateNotegroup(Note note, Chord chord) { if (chord.StartTime != null) { return new Notegroup(note.Duration, (Double)chord.StartTime, GetOrientation(note), Collaborations.GetStatus(note), note, chord); } return null; }
public override void OnClick(object obj) { ObservableCollection<Chord> chords; EA.GetEvent<HideEditPopup>().Publish(string.Empty); if (Infrastructure.Support.Selection.Notes.Any() || Infrastructure.Support.Selection.Arcs.Any()) { //there's an active selection, so stop here and use this click to deselect all selected notes EA.GetEvent<DeSelectAll>().Publish(string.Empty); return; } //notify the parent staff about the click so the staff can do //whatever it needs to do when a Measure is clicked. EA.GetEvent<SendMeasureClickToStaff>().Publish(Measure.Staff_Id); //remove active _measure status from all Measures EA.GetEvent<SetMeasureBackground>().Publish(Guid.Empty); //make this measure the active Measure EA.GetEvent<SetMeasureBackground>().Publish(Measure.Id); if (EditorState.DurationSelected()) { //...the user has clicked on the measure with a note or rest tool. EditorState.Duration = (from a in DurationManager.Durations where (a.Caption == EditorState.DurationCaption) select a.Value).DefaultIfEmpty(Constants.INVALID_DURATION).Single(); if (ValidPlacement()) { EditorState.Measure = Measure; SetChordContext(); _chord = ChordManager.AddNoteToChord(this); //TODO: Why am I updating the provenance panel every time I click a measure? EA.GetEvent<UpdateProvenancePanel>().Publish(CompositionManager.Composition); } } else { //the user clicked with a tool that is not a note or rest. route click to tool dispatcher OnToolClick(); } chords = ChordManager.GetActiveChords(Measure); Duration = (decimal)Convert.ToDouble((from c in chords select c.Duration).Sum()); AdjustMeasureEndSpace(); }