public void FindPartWithSlide() { var slide1 = new SongSlide(song); var slide2 = new SongSlide(song); song.AddPart(new SongPart(song, "NewPart1", new SongSlide[] { slide1 })); song.AddPart(new SongPart(song, "NewPart2", new SongSlide[] { slide2 })); Assert.Equal("NewPart2", song.FindPartWithSlide(slide2).Name); }
public void PartInsertSlideAfter3() { var slide0 = part.Slides.Single(); var slide1 = new SongSlide(song); var slide2 = new SongSlide(song); ClearUndoRedoStack(); Assert.Throws <InvalidOperationException>(() => part.InsertSlideAfter(slide2, slide1)); }
public SongSlide AddSongSlide(SongPart part) { SongSlide sld = new SongSlide { Background = GetDefaultBackground() }; part.Slides.Add(sld); return(sld); }
public void PartInsertSlideAfter2() { var slide0 = part.Slides.Single(); var slide1 = new SongSlide(song); var slide2 = new SongSlide(song); part.AddSlide(slide1); ClearUndoRedoStack(); part.InsertSlideAfter(slide2, slide1); Assert.Equal(3, part.Slides.Count); Assert.Same(slide0, part.Slides[0]); Assert.Same(slide1, part.Slides[1]); Assert.Same(slide2, part.Slides[2]); }
public Song Map(OpenLyricsSong source) { var sng = new Song { // Modified date ModifiedTimestamp = source.ModifiedTimestamp, // Application the song was created in CreatedIn = source.CreatedIn, // Application the song was modified in ModifiedIn = source.ModifiedIn, // Title Title = source.Title, // CCLI CcliIdentifier = source.CcliIdentifier, // Copyright Copyright = source.Copyright, // Application the song was modified in ReleaseYear = source.ReleaseYear }; // // Lyrics // foreach (var verse in source.Verses) { var part = new SongPart { Caption = verse.Name, Language = verse.Language }; foreach (var line in verse.Lines) { var slide = new SongSlide { PartName = line.Part }; slide.Lines.AddRange(line.Text); part.Slides.Add(slide); } sng.Parts.Add(part); } return(sng); }
public Song Map(SongSelectFile source) { var sng = new Song { // CCLI ID CcliIdentifier = source.CcliIdentifier, // Title Title = source.Title, // Copyright Copyright = source.Copyright, // Administration / Rights management RightsManagement = source.Admin }; // Author var a = new SongAuthor { Name = source.Author }; sng.Authors.Add(a); // Themes sng.Themes.AddRange(source.Themes); // Key sng.Key = source.Key; // Verses foreach (var v in source.Verses) { var p = new SongPart { Caption = v.Caption }; var s = new SongSlide(); s.Lines.AddRange(v.Lines); p.Slides.Add(s); sng.Parts.Add(p); } return(sng); }
public void ShowSlide(SongSlide slide) { if (slide == null) { return; // slide might be null if the song has no parts } var s = new { Text = slide.Text, Translation = slide.TranslationWithoutChords, // TODO: does the display controller need to know about chords in the translation? Size = slide.Size, Background = slide.Background, Source = showSource, Copyright = showCopyright }; control.ExecuteJavascript("presentation.showSlide(" + JsonConvert.SerializeObject(s) + ")"); }
public void PartAddSlideExistingUndoRedo() { var slide = new SongSlide(song) { Text = "NewSlide" }; ClearUndoRedoStack(); part.AddSlide(slide); Assert.Equal(2, part.Slides.Count); Assert.Equal(1, UndoStackSize); Undo(); Assert.Equal(1, part.Slides.Count); Assert.Equal("SimpleLine", part.Slides[0].Text); Redo(); Assert.Equal(2, part.Slides.Count); Assert.Equal("NewSlide", part.Slides[1].Text); }
public void CopySlideUndoRedo() { var part0 = song.Parts.Single(); var slide = new SongSlide(song); var part1 = new SongPart(song, "NewPart", new SongSlide[] { slide }); song.AddPart(part1); ClearUndoRedoStack(); song.CopySlide(part0.Slides.Single(), part1); Assert.Equal(2, part1.Slides.Count); Assert.Equal("SimpleLine", part1.Slides[1].Text); Assert.Equal(1, UndoStackSize); Undo(); Assert.Same(slide, part1.Slides.Single()); Redo(); Assert.Equal(2, part1.Slides.Count); Assert.Equal(1, part0.Slides.Count); }
protected Image PreviewSlide(Song sng, string currentText, string currentTranslationText) { SongSlide slide = (SongSlide)sng.Parts[CurrentPartId].Slides[CurrentSlideId].Clone(); slide.Text = currentText; slide.TranslationText = currentTranslationText; SlideTextFormatting slideFormatting = new SlideTextFormatting(); PreviewFormattingMapper.Map(sng, ref slideFormatting); // Disabled for performance slideFormatting.OutlineEnabled = false; slideFormatting.SmoothShadow = false; slideFormatting.ScaleFontSize = Settings.ProjectionFontScaling; slideFormatting.SmoothShadow = false; TextLayer sl = new TextLayer(slideFormatting) { MainText = slide.Lines.ToArray(), SubText = slide.Translation.ToArray() }; sl.DrawBordersForDebugging = Settings.Default.DebugMode; ImageLayer il = new ImageLayer(Settings.ProjectionBackColor); IBackground bg = sng.Parts[CurrentPartId].Slides[CurrentSlideId].Background; il.Image = ImgManager.GetImage(bg); var bmp = new Bitmap(1024, 768); Graphics gr = Graphics.FromImage(bmp); gr.CompositingQuality = CompositingQuality.HighSpeed; gr.SmoothingMode = SmoothingMode.HighSpeed; il.WriteOut(gr, null); sl.WriteOut(gr, null); return(bmp); }
public void MoveSlideAfter() { var part1 = song.Parts.Single(); var slide0 = part1.Slides.Single(); var slide1 = part1.AddSlide(); var slide2 = new SongSlide(song); var part2 = new SongPart(song, "NewPart", new SongSlide[] { slide2 }); song.AddPart(part2); ClearUndoRedoStack(); song.MoveSlideAfter(slide0, slide2); Assert.Equal(1, part1.Slides.Count); Assert.Equal(2, part2.Slides.Count); Assert.Same(slide0, part2.Slides[1]); Assert.Equal(1, UndoStackSize); Undo(); Assert.Equal(2, part1.Slides.Count); Assert.Equal(1, part2.Slides.Count); }
private Tuple <SongSlide, SongPartReference, int> FindSlideByIndex(int index) { int i = 1; SongPartReference pref = null; SongSlide slide = null; foreach (var partRef in song.Order) { pref = partRef; SongPart part = partRef.Part; int iInPart = 0; foreach (var s in part.Slides) { if (i++ == index) { slide = s; return(new Tuple <SongSlide, SongPartReference, int>(slide, pref, iInPart)); } iInPart++; } } return(null); }
public override void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; int lineType = 0; List <string> verseLineList = null; string verseType = null; bool checkFirstLine = false; string copyright = null; while ((line = reader.ReadLine()) != null) { var cleanLine = line.Trim(); if (String.IsNullOrEmpty(cleanLine)) { if (lineType == 0) { continue; } else if (verseLineList != null) // empty line and there were lyrics before -> create part { var part = new SongPart(song, verseType); var slide = new SongSlide(song); slide.Text = String.Join("\n", verseLineList.ToArray()); part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); verseLineList = null; } } else // not an empty line { if (lineType == 0) // very first line -> song title { song.Title = cleanLine; lineType++; } else if (lineType == 1) // lyrics/parts { if (cleanLine.StartsWith("CCLI")) // end of lyrics, start of copyright information { lineType++; string num = cleanLine.Split(' ').Last(); song.CcliNumber = int.Parse(num); } else if (verseLineList == null) { verseType = GetPartName(cleanLine, out checkFirstLine); verseLineList = new List <string>(); } else { if (checkFirstLine) { if (!CheckFirstLine(cleanLine, ref verseType)) { // add text if it was not a part name verseLineList.Add(line); } checkFirstLine = false; } else { verseLineList.Add(line); } } } else if (lineType == 2) // copyright information { if (copyright == null) { copyright = cleanLine; } else { copyright += "\n" + cleanLine; } } } } song.Copyright = copyright; } }
public void LoadComplexTest() { OpenLyricsSongFileMapper mapper = new OpenLyricsSongFileMapper(); OpenLyricsSong source = new OpenLyricsSong { Title = "Amazing Grace", ModifiedTimestamp = "2012-04-10T22:00:00+10:00", CreatedIn = "OpenLP 1.9.0", ModifiedIn = "ChangingSong 0.0.1", CcliIdentifier = "4639462", Copyright = "public domain", ReleaseYear = "1779" }; source.Comments.Add("This is one of the most popular songs in our congregation."); OpenLyricsSong.Verse verse = new OpenLyricsSong.Verse { Name = "v1", Language = "en" }; var lines = new OpenLyricsSong.TextLines(); lines.Text.Add("Amazing grace how sweet the sound that saved a wretch like me;"); verse.Lines.Add(lines); lines = new OpenLyricsSong.TextLines { Part = "women" }; lines.Text.Add("A b c"); lines.Text.Add("D e f"); verse.Lines.Add(lines); source.Verses.Add(verse); verse = new OpenLyricsSong.Verse { Name = "v1", Language = "de" }; lines = new OpenLyricsSong.TextLines(); lines.Text.Add("Erstaunliche Ahmut, wie"); verse.Lines.Add(lines); source.Verses.Add(verse); verse = new OpenLyricsSong.Verse { Name = "c" }; lines = new OpenLyricsSong.TextLines(); lines.Text.Add(""); lines.Text.Add("Line content."); verse.Lines.Add(lines); source.Verses.Add(verse); verse = new OpenLyricsSong.Verse { Name = "v2", Language = "en-US" }; lines = new OpenLyricsSong.TextLines { Part = "men" }; lines.Text.Add(""); lines.Text.Add("Amazing grace how sweet the sound that saved a wretch like me;"); lines.Text.Add(""); lines.Text.Add("Amazing grace how sweet the sound that saved a wretch like me;"); lines.Text.Add("Amazing grace how sweet the sound that saved a wretch like me;"); verse.Lines.Add(lines); lines = new OpenLyricsSong.TextLines { Part = "women" }; lines.Text.Add("A b c"); lines.Text.Add(""); lines.Text.Add("D e f"); verse.Lines.Add(lines); source.Verses.Add(verse); verse = new OpenLyricsSong.Verse { Name = "emptyline", Language = "de" }; lines = new OpenLyricsSong.TextLines(); lines.Text.Add(""); lines.Text.Add(""); verse.Lines.Add(lines); lines = new OpenLyricsSong.TextLines(); lines.Text.Add(""); lines.Text.Add(""); lines.Text.Add(""); lines.Text.Add(""); lines.Text.Add(""); verse.Lines.Add(lines); source.Verses.Add(verse); verse = new OpenLyricsSong.Verse { Name = "e", Language = "de" }; lines = new OpenLyricsSong.TextLines(); lines.Text.Add("This is text of ending."); verse.Lines.Add(lines); source.Verses.Add(verse); Song expected = new Song { Title = "Amazing Grace", ModifiedTimestamp = "2012-04-10T22:00:00+10:00", CreatedIn = "OpenLP 1.9.0", ModifiedIn = "ChangingSong 0.0.1", CcliIdentifier = "4639462", Copyright = "public domain", ReleaseYear = "1779", Comment = "This is one of the most popular songs in our congregation." }; var part = new SongPart { Caption = "v1", Language = "en" }; var slide = new SongSlide(); slide.Lines.Add("Amazing grace how sweet the sound that saved a wretch like me;"); part.Slides.Add(slide); slide = new SongSlide { PartName = "women" }; slide.Lines.Add("A b c"); slide.Lines.Add("D e f"); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "v1", Language = "de" }; slide = new SongSlide { Text = "Erstaunliche Ahmut, wie" }; part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "c" }; slide = new SongSlide(); slide.Lines.Add(""); slide.Lines.Add("Line content."); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "v2", Language = "en-US" }; slide = new SongSlide { PartName = "men" }; slide.Lines.Add(""); slide.Lines.Add("Amazing grace how sweet the sound that saved a wretch like me;"); slide.Lines.Add(""); slide.Lines.Add("Amazing grace how sweet the sound that saved a wretch like me;"); slide.Lines.Add("Amazing grace how sweet the sound that saved a wretch like me;"); part.Slides.Add(slide); slide = new SongSlide { PartName = "women" }; slide.Lines.Add("A b c"); slide.Lines.Add(""); slide.Lines.Add("D e f"); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "emptyline", Language = "de" }; slide = new SongSlide(); slide.Lines.Add(""); slide.Lines.Add(""); part.Slides.Add(slide); slide = new SongSlide(); slide.Lines.Add(""); slide.Lines.Add(""); slide.Lines.Add(""); slide.Lines.Add(""); slide.Lines.Add(""); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "e", Language = "de" }; slide = new SongSlide { Text = "This is text of ending." }; part.Slides.Add(slide); expected.Parts.Add(part); Song actual = mapper.Map(source); Assert.AreEqual(expected.Title, actual.Title, "Wrong song title"); Assert.AreEqual(expected.ModifiedTimestamp, actual.ModifiedTimestamp, "Wrong song modified date"); Assert.AreEqual(expected.CreatedIn, actual.CreatedIn, "Wrong creator app"); Assert.AreEqual(expected.ModifiedIn, actual.ModifiedIn, "Wrong modifier app"); Assert.AreEqual(expected.Copyright, actual.Copyright, "Wrong copyright info"); Assert.AreEqual(expected.CcliIdentifier, actual.CcliIdentifier, "Wrong CCLI number"); Assert.AreEqual(expected.ReleaseYear, actual.ReleaseYear, "Wrong release date"); Assert.AreEqual(expected.Parts.Count, actual.Parts.Count, "Parts incomplete"); for (int i = 0; i < expected.Parts.Count; i++) { Assert.AreEqual(expected.Parts[i].Caption, actual.Parts[i].Caption, "Wrong verse name"); Assert.AreEqual(expected.Parts[i].Language, actual.Parts[i].Language, "Wrong language"); Assert.AreEqual(expected.Parts[i].Slides.Count, actual.Parts[i].Slides.Count, "Slides incomplete " + i); for (int j = 0; j < expected.Parts[i].Slides.Count; j++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines.Count, actual.Parts[i].Slides[j].Lines.Count, "Slide lines incomplete " + i + " " + j); Assert.AreEqual(expected.Parts[i].Slides[j].PartName, actual.Parts[i].Slides[j].PartName, "Wrong slide part name"); for (int k = 0; k < expected.Parts[i].Slides[j].Lines.Count; k++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines[k], actual.Parts[i].Slides[j].Lines[k], "Wrong slide lyrics"); } } } }
public void LoadSimpleTest() { OpenLyricsSongFileMapper mapper = new OpenLyricsSongFileMapper(); OpenLyricsSong source = new OpenLyricsSong { Title = "Amazing Grace", ModifiedTimestamp = "2012-04-10T22:00:00+10:00", CreatedIn = "OpenLP 1.9.0", ModifiedIn = "MyApp 0.0.1" }; OpenLyricsSong.Verse verse = new OpenLyricsSong.Verse { Name = "v1" }; OpenLyricsSong.TextLines lines = new OpenLyricsSong.TextLines(); lines.Text.Add("Amazing grace how sweet the sound"); lines.Text.Add("that saved a wretch like me;"); verse.Lines.Add(lines); source.Verses.Add(verse); Song expected = new Song { Title = "Amazing Grace", ModifiedTimestamp = "2012-04-10T22:00:00+10:00", CreatedIn = "OpenLP 1.9.0", ModifiedIn = "MyApp 0.0.1" }; var part = new SongPart { Caption = "v1" }; var slide = new SongSlide { Text = "Amazing grace how sweet the sound<br/>that saved a wretch like me;" }; part.Slides.Add(slide); expected.Parts.Add(part); var actual = mapper.Map(source); Assert.AreEqual(expected.Title, actual.Title, "Wrong song title"); Assert.AreEqual(expected.ModifiedTimestamp, actual.ModifiedTimestamp, "Wrong song modified date"); Assert.AreEqual(expected.CreatedIn, actual.CreatedIn, "Wrong creator app"); Assert.AreEqual(expected.ModifiedIn, actual.ModifiedIn, "Wrong modifier app"); Assert.AreEqual(expected.Parts.Count, actual.Parts.Count, "Parts incomplete"); for (int i = 0; i < expected.Parts.Count; i++) { Assert.AreEqual(expected.Parts[i].Caption, actual.Parts[i].Caption, "Wrong verse name"); Assert.AreEqual(expected.Parts[i].Slides.Count, actual.Parts[i].Slides.Count, "Slides incomplete"); for (int j = 0; j < expected.Parts[i].Slides.Count; j++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines.Count, actual.Parts[i].Slides[j].Lines.Count, "Slide lines incomplete"); for (int k = 0; k < expected.Parts[i].Slides[j].Lines.Count; k++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines[k], actual.Parts[i].Slides[j].Lines[k], "Wrong slide lyrics"); } } } Assert.IsTrue(SongSearchUtil.GetSearchableSongText(actual).Contains(expected.Title.ToLower())); Assert.IsTrue(SongSearchUtil.GetSearchableSongText(actual).Contains("sweet")); }
public override void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; int lineType = 0; List<string> verseLineList = null; string verseType = null; bool checkFirstLine = false; string copyright = null; while ((line = reader.ReadLine()) != null) { var cleanLine = line.Trim(); if (String.IsNullOrEmpty(cleanLine)) { if (lineType == 0) { continue; } else if (verseLineList != null) // empty line and there were lyrics before -> create part { var part = new SongPart(song, verseType); var slide = new SongSlide(song); slide.Text = String.Join("\n", verseLineList.ToArray()); part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); verseLineList = null; } } else // not an empty line { if (lineType == 0) // very first line -> song title { song.Title = cleanLine; lineType++; } else if (lineType == 1) // lyrics/parts { if (cleanLine.StartsWith("CCLI")) // end of lyrics, start of copyright information { lineType++; string num = cleanLine.Split(' ').Last(); song.CcliNumber = int.Parse(num); } else if (verseLineList == null) { verseType = GetPartName(cleanLine, out checkFirstLine); verseLineList = new List<string>(); } else { if (checkFirstLine) { if (!CheckFirstLine(cleanLine, ref verseType)) { // add text if it was not a part name verseLineList.Add(line); } checkFirstLine = false; } else { verseLineList.Add(line); } } } else if (lineType == 2) // copyright information { if (copyright == null) { copyright = cleanLine; } else { copyright += "\n" + cleanLine; } } } } song.Copyright = copyright; } }
private void FinishPart(Song song, string key, List <LineGroup> lineGroups, LineGroup lastLineGroup) { if (lastLineGroup != null) { lineGroups.Add(lastLineGroup); } if (lineGroups.Count == 0) { throw new SongFormatException("File is not a valid OpenSong song: Empty part"); } foreach (var lg in lineGroups) { if (lg.Lines.Count == 0) { lg.Lines.Add(new Line { Text = "" }); } } var noNumbers = !lineGroups[0].Lines[0].Number.HasValue; if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue))) { throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines."); } int maxVerseNumber; if (noNumbers) { maxVerseNumber = 1; } else { maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value)); } for (int i = 1; i <= maxVerseNumber; i++) { if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i))) { continue; } string name; if (noNumbers) { name = GetPartName(key); } else { name = GetPartName(key + i.ToString()); } var part = new SongPart(song, name); var slide = new SongSlide(song); slide.Text = String.Join("\n", lineGroups. Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)). Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords))); part.AddSlide(slide); // apply slide breaks int ind; while ((ind = slide.Text.IndexOf("||")) >= 0) { slide.Text = slide.Text.Remove(ind, 2); part.SplitSlide(slide, ind); } // apply line breaks foreach (var s in part.Slides) { s.Text = s.Text.Replace("|", "\n"); } song.AddPart(part); } }
private void treeViewContents_AfterSelect(object sender, TreeViewEventArgs e) { int partId = -1; int slideId = -1; if (treeViewContents.SelectedNode.Level == 1) { partId = treeViewContents.SelectedNode.Parent.Index; slideId = treeViewContents.SelectedNode.Index; buttonDelItem.Enabled = Song.Parts[partId].Slides.Count > 1; buttonMoveDown.Enabled = slideId < Song.Parts[partId].Slides.Count - 1; buttonMoveUp.Enabled = slideId > 0; buttonDuplicateSlide.Enabled = true; } else if (treeViewContents.SelectedNode.Level == 0) { partId = treeViewContents.SelectedNode.Index; buttonDelItem.Enabled = Song.Parts.Count > 1; buttonMoveDown.Enabled = partId < Song.Parts.Count - 1; buttonMoveUp.Enabled = partId > 0; buttonDuplicateSlide.Enabled = false; } else { buttonDelItem.Enabled = false; buttonMoveDown.Enabled = false; buttonMoveUp.Enabled = false; buttonDuplicateSlide.Enabled = false; } if (partId < 0) { partId = CurrentPartId; } if (slideId < 0) { slideId = CurrentSlideId; } if (partId >= Song.Parts.Count) { partId = Song.Parts.Count - 1; } if (slideId >= Song.Parts[partId].Slides.Count) { slideId = Song.Parts[partId].Slides.Count - 1; } SongSlide sld = Song.Parts[partId].Slides[slideId]; textBoxSongText.DataBindings.Clear(); textBoxSongText.DataBindings.Add("Text", sld, "Text"); textBoxSongTranslation.DataBindings.Clear(); textBoxSongTranslation.DataBindings.Add("Text", sld, "TranslationText"); CurrentPartId = partId; CurrentSlideId = slideId; PreviewSlide(); }
public void PartRemoveSlideDisconnected() { var slide1 = new SongSlide(song); Assert.Throws <InvalidOperationException>(() => part.RemoveSlide(slide1)); }
public override void Init() { base.Init(); part = song.Parts.Single(); slide = part.Slides.Single(); }
private void FinishPart(Song song, string key, List<LineGroup> lineGroups, LineGroup lastLineGroup) { if (lastLineGroup != null) lineGroups.Add(lastLineGroup); if (lineGroups.Count == 0) throw new SongFormatException("File is not a valid OpenSong song: Empty part"); foreach (var lg in lineGroups) { if (lg.Lines.Count == 0) lg.Lines.Add(new Line { Text = "" }); } var noNumbers = !lineGroups[0].Lines[0].Number.HasValue; if (noNumbers && lineGroups.Any(lg => lg.Lines.Any(l => l.Number.HasValue))) throw new SongFormatException("File is not a valid OpenSong song: Found mixed numbered and unnumbered lines."); int maxVerseNumber; if (noNumbers) { maxVerseNumber = 1; } else { maxVerseNumber = lineGroups.Max(lg => lg.Lines.Max(l => l.Number.Value)); } for (int i = 1; i <= maxVerseNumber; i++) { if (!noNumbers && !lineGroups.Any(lg => lg.Lines.Any(l => l.Number == i))) continue; string name; if (noNumbers) name = GetPartName(key); else name = GetPartName(key + i.ToString()); var part = new SongPart(song, name); var slide = new SongSlide(song); slide.Text = String.Join("\n", lineGroups. Where(lg => lg.Lines.Any(l => noNumbers || l.Number == i)). Select(lg => PrepareLine(lg.Lines.Where(l => noNumbers || l.Number == i).Single().Text, lg.Chords))); part.AddSlide(slide); // apply slide breaks int ind; while ((ind = slide.Text.IndexOf("||")) >= 0) { slide.Text = slide.Text.Remove(ind, 2); part.SplitSlide(slide, ind); } // apply line breaks foreach (var s in part.Slides) { s.Text = s.Text.Replace("|", "\n"); } song.AddPart(part); } }
private void StructureTree_Drop(object sender, DragEventArgs e) { try { var tree = (TreeView)sender; if (e.Data.GetData(typeof(SongSlide)) != null) { ISongElement targetNode = tree.GetItemAtPosition(e.GetPosition(tree)).Header as ISongElement; SongSlide dragNode = e.Data.GetData(typeof(SongSlide)) as SongSlide; if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) // copy { if (targetNode is SongSlide) { song.CopySlideAfter(dragNode, targetNode as SongSlide); } else if (targetNode is SongPart) { song.CopySlide(dragNode, targetNode as SongPart); } } else { if (targetNode == dragNode) { return; } if (song.FindPartWithSlide(dragNode).Slides.Count <= 1) { MessageBox.Show(Resource.eMsgMoveLastSlideInPart, Resource.dialogError, MessageBoxButton.OK, MessageBoxImage.Error); return; } if (targetNode is SongSlide) { song.MoveSlideAfter(dragNode, targetNode as SongSlide); } else if (targetNode is SongPart) { song.MoveSlide(dragNode, targetNode as SongPart); } tree.SelectItem(dragNode); } } else if (e.Data.GetData(typeof(SongPart)) != null) { ISongElement targetNode = tree.GetItemAtPosition(e.GetPosition(tree)).Header as ISongElement; SongPart dragNode = e.Data.GetData(typeof(SongPart)) as SongPart; SongPart targetPart; if (targetNode is SongSlide) { targetPart = song.FindPartWithSlide(targetNode as SongSlide); } else { targetPart = (SongPart)targetNode; } if (e.KeyStates.HasFlag(DragDropKeyStates.ControlKey)) { // copy part: request name for the copy first var res = ShowRenamePartDialog(null); if (res.DialogResult.HasValue && res.DialogResult.Value) { SongPart newPart = song.CopyPart(dragNode, res.PartName, targetPart); tree.SelectItem(newPart); } } else { song.MovePart(dragNode, targetPart); tree.SelectItem(dragNode); } } } catch (Exception ex) { Controller.ShowUnhandledException(ex, false); } }
// documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py // [File] // USR file format first line // Type= // Indicates the file type // e.g. Type=SongSelect Import File // Version=3.0 // File format version // [S A2672885] // Contains the CCLI Song number e.g. 2672885 // Title= // Contains the song title (e.g. Title=Above All) // Author= // Contains a | delimited list of the song authors // e.g. Author=LeBlanc, Lenny | Baloche, Paul // Copyright= // Contains a | delimited list of the song copyrights // e.g. Copyright=1999 Integrity's Hosanna! Music | // LenSongs Publishing (Verwaltet von Gerth Medien // Musikverlag) // Admin= // Contains the song administrator // e.g. Admin=Gerth Medien Musikverlag // Themes= // Contains a /t delimited list of the song themes // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer // Keys= // Contains the keys in which the music is played?? // e.g. Keys=A // Fields= // Contains a list of the songs fields in order /t delimited // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1 // Words= // Contains the songs various lyrics in order as shown by the // Fields description // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF] public override void Read(Song song, Stream stream) { if (song == null) { throw new ArgumentNullException("song"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; string authors = null; string copyright = null; string[] fieldsList = null; string[] wordsList = null; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("[S ")) { // CCLI Song number int end = line.IndexOf(']'); if (end > 1) { string num = line.Substring(3, end - 3); if (num.StartsWith("A")) { num = num.Substring(1); } song.CcliNumber = int.Parse(num); } } else if (line.StartsWith("Title=")) { song.Title = line.Substring("Title=".Length).Trim(); } else if (line.StartsWith("Author=")) { var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray(); authors = String.Join(", ", authorList); } else if (line.StartsWith("Copyright=")) { copyright = line.Substring("Copyright=".Length).Trim(); } else if (line.StartsWith("Themes=")) { var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t"). Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); song.Category = String.Join(", ", themesList); } else if (line.StartsWith("Fields=")) { fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } else if (line.StartsWith("Words=")) { wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } // Unhandled usr keywords: Type, Version, Admin, Keys } if (fieldsList == null || wordsList == null || authors == null || copyright == null) { throw new SongFormatException("Missing field in USR file."); } var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length; for (int i = 0; i < partNum; i++) { bool checkFirstLine; var partName = GetPartName(fieldsList[i], out checkFirstLine); string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd(); if (checkFirstLine) { var lines = text.Split('\n'); var firstLine = lines[0].Trim(); if (CheckFirstLine(firstLine, ref partName)) { text = text.Substring(text.IndexOf('\n') + 1); } } var part = new SongPart(song, partName); var slide = new SongSlide(song); slide.Text = text; part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); } song.Copyright = authors + "\n© " + copyright; } }
/// <summary> /// Parses text to song structure /// Aimed to be used for CCLI SongSelect lyrics, but should work with other lyrics too /// </summary> /// <param name="text"></param> /// <returns></returns> public Song Parse(string text) { string trimmed = text.Trim(); string[] lines = trimmed.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None); if (lines.Length == 0 || trimmed.Length == 0) { throw new Exception("Leeres Lied!"); } Song song = new Song(); if (lines.Length > 1 && lines[0] != string.Empty && lines[1] == string.Empty) { song.Title = lines[0]; lines = lines.Skip(2).ToArray(); } State state = State.Separator; SongPart part = null; SongSlide slide = null; List <string> copyright = new List <string>(); foreach (string line in lines) { if (line != string.Empty && state == State.Separator) { if (line.StartsWith("CCLI Song #")) { state = State.Meta; Regex regex = new Regex(@"CCLI Song #\s*(\d+)"); Match match = regex.Match(line); if (match.Success) { song.CcliIdentifier = match.Groups[1].Value; } continue; } state = State.Verse; slide = new SongSlide(); part = new SongPart(); part.Slides.Add(slide); var splittedLine = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); if (defaultPartNames.Any(splittedLine[0].Contains)) { part.Caption = line; } else if (PartNames.Contains(line)) { part.Caption = line; } else { int idx = 1; string partPrefix = defaultPartPrefix + idx; while (song.Parts.Any(i => i.Caption == partPrefix)) { partPrefix = defaultPartPrefix + ++idx; } part.Caption = partPrefix; slide.Lines.Add(line); } continue; } if (line != string.Empty && state == State.Verse) { slide.Lines.Add(line); continue; } if (line != string.Empty && state == State.Meta) { if (line.StartsWith("CCLI License #") || line.StartsWith("For use solely with the SongSelect")) { continue; } copyright.Add(line); continue; } if (line == string.Empty && state == State.Verse) { state = State.Separator; song.Parts.Add(part); song.PartSequence.Add(part); continue; } } if (state == State.Verse) { state = State.Separator; song.Parts.Add(part); song.PartSequence.Add(part); } if (copyright.Count > 0) { song.Copyright = string.Join(Environment.NewLine, copyright.ToArray()); } return(song); }
public static Song GetExpectedSong() { Song song = new Song { Title = "Näher, mein Gott, zu Dir", Language = "Deutsch" }; song.Themes.Add("Anbetung"); song.Copyright = "Text und Musik: Lowell Mason, 1792-1872"; song.Formatting = new SongFormatting(); song.Formatting.CopyrightPosition = AdditionalInformationPosition.LastSlide; SongBook sb = new SongBook { Name = "grünes Buch 339" }; song.SongBooks.Add(sb); song.Formatting.SourcePosition = AdditionalInformationPosition.FirstSlide; SongPart part = new SongPart { Caption = "Teil 1" }; SongSlide slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 42 }; slide.Lines.Add("Näher, mein Gott, zu Dir,"); slide.Lines.Add("sei meine Bitt'!"); slide.Lines.Add("Näher, o Herr, zu Dir"); slide.Lines.Add("mit jedem Schritt."); part.Slides.Add(slide); slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 44 }; slide.Lines.Add("Nur an dem Herzen Dein"); slide.Lines.Add("kann ich geborgen sein;"); slide.Lines.Add("deshalb die Bitte mein:"); slide.Lines.Add("Näher zu Dir!"); part.Slides.Add(slide); song.Parts.Add(part); part = new SongPart { Caption = "Teil 2" }; slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 42 }; slide.Lines.Add("Näher, mein Gott, zu Dir!"); slide.Lines.Add("Ein jeder Tag"); slide.Lines.Add("soll es neu zeigen mir,"); slide.Lines.Add("was er vermag:"); part.Slides.Add(slide); slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 42 }; slide.Lines.Add("Wie seiner Gnade Macht,"); slide.Lines.Add("Erlösung hat gebracht,"); slide.Lines.Add("in uns're Sündennacht."); slide.Lines.Add("Näher zu Dir!"); part.Slides.Add(slide); song.Parts.Add(part); part = new SongPart { Caption = "Teil 3" }; slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 42 }; slide.Lines.Add("Näher, mein Gott, zu Dir!"); slide.Lines.Add("Dich bet' ich an."); slide.Lines.Add("Wie vieles hast an mir,"); slide.Lines.Add("Du doch getan!"); part.Slides.Add(slide); slide = new SongSlide { Background = new ImageBackground("Blumen\\Blume 3.jpg"), TextSize = 42 }; slide.Lines.Add("Von Banden frei und los,"); slide.Lines.Add("ruh' ich in Deinem Schoss."); slide.Lines.Add("Ja, Deine Gnad' ist gross!"); slide.Lines.Add("Näher zu Dir!"); part.Slides.Add(slide); song.Parts.Add(part); song.PartSequence.Add(song.Parts[0]); song.PartSequence.Add(song.Parts[1]); song.PartSequence.Add(song.Parts[2]); song.Formatting.MainText = new TextFormatting( new Font("Times New Roman", 44, FontStyle.Bold | FontStyle.Italic), Color.White, new TextOutline(30, Color.Black), new TextShadow(15, 0, 125, Color.Black) ); song.Formatting.TranslationText = new TextFormatting( new Font("Times New Roman", 20, FontStyle.Regular), Color.White, new TextOutline(30, Color.Black), new TextShadow(20, 0, 125, Color.Black) ); song.Formatting.CopyrightText = new TextFormatting( new Font("Times New Roman", 14, FontStyle.Regular), Color.White, new TextOutline(30, Color.Black), new TextShadow(20, 0, 125, Color.Black) ); song.Formatting.SourceText = new TextFormatting( new Font("Times New Roman", 30, FontStyle.Regular), Color.White, new TextOutline(30, Color.Black), new TextShadow(20, 0, 125, Color.Black) ); song.Formatting.MainLineSpacing = 30; song.Formatting.TranslationLineSpacing = 20; song.Formatting.TextOrientation = new TextOrientation(VerticalOrientation.Middle, HorizontalOrientation.Left); song.Formatting.TextOutlineEnabled = false; song.Formatting.TextShadowEnabled = true; song.Formatting.TextBorders = new SongTextBorders(50, 40, 60, 70, 30, 20, 40); return(song); }
// documentation taken from http://bazaar.launchpad.net/~openlp-core/openlp/trunk/view/head:/openlp/plugins/songs/lib/cclifileimport.py // [File] // USR file format first line // Type= // Indicates the file type // e.g. Type=SongSelect Import File // Version=3.0 // File format version // [S A2672885] // Contains the CCLI Song number e.g. 2672885 // Title= // Contains the song title (e.g. Title=Above All) // Author= // Contains a | delimited list of the song authors // e.g. Author=LeBlanc, Lenny | Baloche, Paul // Copyright= // Contains a | delimited list of the song copyrights // e.g. Copyright=1999 Integrity's Hosanna! Music | // LenSongs Publishing (Verwaltet von Gerth Medien // Musikverlag) // Admin= // Contains the song administrator // e.g. Admin=Gerth Medien Musikverlag // Themes= // Contains a /t delimited list of the song themes // e.g. Themes=Cross/tKingship/tMajesty/tRedeemer // Keys= // Contains the keys in which the music is played?? // e.g. Keys=A // Fields= // Contains a list of the songs fields in order /t delimited // e.g. Fields=Vers 1/tVers 2/tChorus 1/tAndere 1 // Words= // Contains the songs various lyrics in order as shown by the // Fields description // e.g. Words=Above all powers.... [/n = CR, /n/t = CRLF] public override void Read(Song song, Stream stream) { if (song == null) throw new ArgumentNullException("song"); if (stream == null) throw new ArgumentNullException("stream"); using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { string line; string authors = null; string copyright = null; string[] fieldsList = null; string[] wordsList = null; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("[S ")) { // CCLI Song number int end = line.IndexOf(']'); if (end > 1) { string num = line.Substring(3, end - 3); if (num.StartsWith("A")) num = num.Substring(1); song.CcliNumber = int.Parse(num); } } else if (line.StartsWith("Title=")) { song.Title = line.Substring("Title=".Length).Trim(); } else if (line.StartsWith("Author=")) { var authorList = line.Substring("Author=".Length).Trim().Split('|').Select(s => s.Trim()).ToArray(); authors = String.Join(", ", authorList); } else if (line.StartsWith("Copyright=")) { copyright = line.Substring("Copyright=".Length).Trim(); } else if (line.StartsWith("Themes=")) { var themesList = line.Substring("Themes=".Length).Trim().Replace(" | ", "/t"). Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); song.Category = String.Join(", ", themesList); } else if (line.StartsWith("Fields=")) { fieldsList = line.Substring("Fields=".Length).Trim().Split(new string[] {"/t"}, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } else if (line.StartsWith("Words=")) { wordsList = line.Substring("Words=".Length).Trim().Split(new string[] { "/t" }, StringSplitOptions.None).Select(s => s.Trim()).ToArray(); } // Unhandled usr keywords: Type, Version, Admin, Keys } if (fieldsList == null || wordsList == null || authors == null || copyright == null) { throw new SongFormatException("Missing field in USR file."); } var partNum = (fieldsList.Length < wordsList.Length) ? fieldsList.Length : wordsList.Length; for (int i = 0; i < partNum; i++) { bool checkFirstLine; var partName = GetPartName(fieldsList[i], out checkFirstLine); string text = wordsList[i].Replace("/n", "\n").Replace(" | ", "\n").TrimEnd(); if (checkFirstLine) { var lines = text.Split('\n'); var firstLine = lines[0].Trim(); if (CheckFirstLine(firstLine, ref partName)) { text = text.Substring(text.IndexOf('\n') + 1); } } var part = new SongPart(song, partName); var slide = new SongSlide(song); slide.Text = text; part.AddSlide(slide); song.AddPart(part); song.AddPartToOrder(part); } song.Copyright = authors + "\n© " + copyright; } }
/// <summary> /// Maps a PowerPraise song to a Song object /// </summary> /// <param name="ppl"></param> /// <returns></returns> public Song Map(PowerPraiseSong ppl) { var song = new Song { Title = ppl.Title, Language = ppl.Language }; if (ppl.Category != PowerPraiseConstants.NoCategory) { song.Themes.Add(ppl.Category); } // Copyright text song.Copyright = string.Join(Environment.NewLine, ppl.CopyrightText.ToArray()); song.Formatting = new SongFormatting(); song.Formatting.CopyrightPosition = ppl.Formatting.CopyrightTextPosition; // Source / songbook song.SongBooks.FromString(ppl.SourceText); song.Formatting.SourcePosition = ppl.Formatting.SourceTextPosition; // Song parts foreach (var prt in ppl.Parts) { var part = new SongPart { Caption = prt.Caption }; foreach (var sld in prt.Slides) { var slide = new SongSlide(); if (sld.Background != null) { slide.Background = (IBackground)sld.Background.Clone(); } slide.TextSize = sld.MainSize > 0 ? sld.MainSize : (song.Formatting.MainText.Font != null ? song.Formatting.MainText.Font.Size : 0); slide.Lines.AddRange(sld.Lines); slide.Translation.AddRange(sld.Translation); part.Slides.Add(slide); } song.Parts.Add(part); } // Order foreach (var o in ppl.Order) { foreach (var p in song.Parts) { if (p.Caption == o.Caption) { song.PartSequence.Add(p); break; } } } MapFormatting(ppl, song); return(song); }
public void LoadTest() { SongSelectFileMapper mapper = new SongSelectFileMapper(); SongSelectFile source = new SongSelectFile { Title = "Ein Lied für Gott", Author = "Muster, Hans", Copyright = "Gemeinfrei (Public Domain)", Admin = "Verlag ABC", Key = "E" }; source.Themes.Add("Celebration"); source.Themes.Add("God's Attributes"); source.Themes.Add("Love"); source.Themes.Add("Joy"); var verse = new SongSelectFile.Verse { Caption = "Vers 1" }; verse.Lines.Add("Lorem ipsum dolor sit amet,"); verse.Lines.Add("consectetur adipiscing elit."); verse.Lines.Add("Vivamus odio massa,"); verse.Lines.Add("lacinia in mollis quis,"); verse.Lines.Add("vehicula sed justo"); source.Verses.Add(verse); verse = new SongSelectFile.Verse { Caption = "Vers 2" }; verse.Lines.Add("Nunc cursus libero non quam lobortis"); verse.Lines.Add("ac pharetra leo facilisis."); verse.Lines.Add("Proin tortor tellus,"); verse.Lines.Add("fermentum mattis euismod eu,"); verse.Lines.Add("faucibus vel justo."); source.Verses.Add(verse); verse = new SongSelectFile.Verse { Caption = "Vers 3" }; verse.Lines.Add("Fusce pellentesque rhoncus felis,"); verse.Lines.Add("eu convallis ante tempus a."); verse.Lines.Add("Cum sociis natoque penatibus"); verse.Lines.Add("et magnis dis parturient montes,"); verse.Lines.Add("nascetur ridiculus mus."); source.Verses.Add(verse); Song expected = new Song { Title = "Ein Lied für Gott" }; expected.Themes.Add("Celebration"); expected.Themes.Add("God's Attributes"); expected.Themes.Add("Love"); expected.Themes.Add("Joy"); var aut = new SongAuthor { Name = "Muster, Hans" }; expected.Authors.Add(aut); expected.Copyright = "Gemeinfrei (Public Domain)"; expected.RightsManagement = "Verlag ABC"; expected.Key = "E"; var part = new SongPart { Caption = "Vers 1" }; var slide = new SongSlide(); slide.Lines.Add("Lorem ipsum dolor sit amet,"); slide.Lines.Add("consectetur adipiscing elit."); slide.Lines.Add("Vivamus odio massa,"); slide.Lines.Add("lacinia in mollis quis,"); slide.Lines.Add("vehicula sed justo"); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "Vers 2" }; slide = new SongSlide(); slide.Lines.Add("Nunc cursus libero non quam lobortis"); slide.Lines.Add("ac pharetra leo facilisis."); slide.Lines.Add("Proin tortor tellus,"); slide.Lines.Add("fermentum mattis euismod eu,"); slide.Lines.Add("faucibus vel justo."); part.Slides.Add(slide); expected.Parts.Add(part); part = new SongPart { Caption = "Vers 3" }; slide = new SongSlide(); slide.Lines.Add("Fusce pellentesque rhoncus felis,"); slide.Lines.Add("eu convallis ante tempus a."); slide.Lines.Add("Cum sociis natoque penatibus"); slide.Lines.Add("et magnis dis parturient montes,"); slide.Lines.Add("nascetur ridiculus mus."); part.Slides.Add(slide); expected.Parts.Add(part); Song actual = mapper.Map(source); Assert.AreEqual(expected.Title, actual.Title, "Wrong song title"); Assert.AreEqual(expected.Language, actual.Language, "Wrong language"); Assert.AreEqual(expected.Copyright, actual.Copyright, "Wrong copyright"); Assert.AreEqual(expected.RightsManagement, actual.RightsManagement, "Wrong RightsManagement"); Assert.AreEqual(expected.Key, actual.Key, "Wrong key"); for (int i = 0; i < expected.Themes.Count; i++) { Assert.AreEqual(expected.Themes[i], actual.Themes[i], "Wrong theme"); } for (int i = 0; i < expected.Authors.Count; i++) { Assert.AreEqual(expected.Authors[i].Name, actual.Authors[i].Name, "Wrong Author"); } Assert.AreEqual(expected.Parts.Count, actual.Parts.Count, "Parts incomplete"); for (int i = 0; i < expected.Parts.Count; i++) { Assert.AreEqual(expected.Parts[i].Caption, actual.Parts[i].Caption, "Wrong verse name in verse " + i); Assert.AreEqual(expected.Parts[i].Slides.Count, actual.Parts[i].Slides.Count, "Slides incomplete in verse " + i); for (int j = 0; j < expected.Parts[i].Slides.Count; j++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines.Count, actual.Parts[i].Slides[j].Lines.Count, "Slide lines incomplete in verse " + i + " slide " + j); for (int k = 0; k < expected.Parts[i].Slides[j].Lines.Count; k++) { Assert.AreEqual(expected.Parts[i].Slides[j].Lines[k], actual.Parts[i].Slides[j].Lines[k], "Wrong slide lyrics"); } } } }