コード例 #1
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Removes a specified slide from this part (can be undone).
        /// </summary>
        /// <param name="slide"></param>
        public void RemoveSlide(SongSlide slide)
        {
            if (slide == null)
            {
                throw new ArgumentNullException("slide");
            }

            if (Slides.Count <= 1)
            {
                throw new InvalidOperationException("Can't remove last slide in a part.");
            }

            int i = Slides.IndexOf(slide);

            if (i < 0)
            {
                throw new InvalidOperationException("Slide is not in this part.");
            }

            Undo.ChangeFactory.OnChanging(this,
                                          () => { slides.Insert(i, slide); },
                                          () => { slides.Remove(slide); },
                                          "RemoveSlide");
            slides.Remove(slide);
        }
コード例 #2
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Splits a slide at a specified index. The first part remains in the original slide
        /// and the rest is moved to a new slide (can be undone).
        /// </summary>
        /// <param name="slide">The slide to split.</param>
        /// <param name="splitIndex">The index to split at.</param>
        /// <returns>A new slide containing the rest of the text after the split index.</returns>
        public SongSlide SplitSlide(SongSlide slide, int splitIndex)
        {
            SongSlide newSlide;

            using (Undo.ChangeFactory.Batch(this, "SplitSlide"))
            {
                var textBefore = slide.Text.Substring(0, splitIndex);
                if (textBefore.EndsWith("\r\n"))
                {
                    textBefore = textBefore.Substring(0, textBefore.Length - 2);
                }
                else if (textBefore.EndsWith("\n"))
                {
                    textBefore = textBefore.Substring(0, textBefore.Length - 1);
                }
                var textAfter = slide.Text.Substring(splitIndex);
                if (textAfter.StartsWith("\r\n"))
                {
                    textAfter = textAfter.Substring(2);
                }
                else if (textAfter.StartsWith("\n"))
                {
                    textAfter = textAfter.Substring(1);
                }
                newSlide      = DuplicateSlide(slide);
                slide.Text    = textBefore;
                newSlide.Text = textAfter;
            }
            return(newSlide);
        }
コード例 #3
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
 /// <summary>
 /// Adds an existing slide to this part (can be undone).
 /// </summary>
 /// <param name="slide">The slide to add.</param>
 public void AddSlide(SongSlide slide)
 {
     Undo.ChangeFactory.OnChanging(this,
                                   () => { slides.Remove(slide); },
                                   () => { slides.Add(slide); },
                                   "AddSlide");
     slides.Add(slide);
 }
コード例 #4
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Adds an empty slide to the part (can be undone).
        /// </summary>
        /// <returns>The newly created slide.</returns>
        public SongSlide AddSlide()
        {
            SongSlide slide;

            slide = new SongSlide(Root);
            AddSlide(slide);

            return(slide);
        }
コード例 #5
0
        /// <summary>
        /// Copies this slide.
        /// </summary>
        /// <returns>A copy of this slide.</returns>
        public SongSlide Copy()
        {
            var s = new SongSlide(Root);

            s.Text            = Text;
            s.Translation     = Translation;
            s.BackgroundIndex = BackgroundIndex;
            s.Size            = Size;
            return(s);
        }
コード例 #6
0
ファイル: Song.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Moves a slide to another part (can be undone).
        /// </summary>
        /// <param name="slide">The slide to move.</param>
        /// <param name="target">The target part.</param>
        public void MoveSlide(SongSlide slide, SongPart target)
        {
            var part = FindPartWithSlide(slide);

            using (Undo.ChangeFactory.Batch(this, "MoveSlide"))
            {
                part.RemoveSlide(slide);
                target.AddSlide(slide);
            }
        }
コード例 #7
0
ファイル: Song.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Copies the specified slide into a given part.
        /// The copy will be appended to the part's slide list
        /// (can be undone).
        /// </summary>
        /// <param name="slide">The slide to copy.</param>
        /// <param name="target">The part where the copy will be inserted.</param>
        /// <returns>The copy.</returns>
        public SongSlide CopySlide(SongSlide slide, SongPart target)
        {
            SongSlide s;
            var       part = FindPartWithSlide(slide);

            using (Undo.ChangeFactory.Batch(this, "CopySlide"))
            {
                s = slide.Copy();
                target.AddSlide(s);
            }

            return(s);
        }
コード例 #8
0
ファイル: Song.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Copies a slide and inserts it after another slide (can be undone).
        /// </summary>
        /// <param name="slide">The slide to copy</param>
        /// <param name="target">The slide after which the copy will be inserted.</param>
        /// <returns>The copy.</returns>
        public SongSlide CopySlideAfter(SongSlide slide, SongSlide target)
        {
            SongSlide s;
            var       part       = FindPartWithSlide(slide);
            var       targetPart = FindPartWithSlide(target);

            using (Undo.ChangeFactory.Batch(this, "CopySlideAfter"))
            {
                s = slide.Copy();
                targetPart.InsertSlideAfter(s, target);
            }

            return(s);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
ファイル: Song.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Moves a slide to the position directly after another slide (can be undone).
        /// </summary>
        /// <param name="slide">The slide to move.</param>
        /// <param name="target">The target slide.</param>
        public void MoveSlideAfter(SongSlide slide, SongSlide target)
        {
            if (slide == target)
            {
                return;
            }

            var part       = FindPartWithSlide(slide);
            var targetPart = FindPartWithSlide(target);

            using (Undo.ChangeFactory.Batch(this, "MoveSlide"))
            {
                part.RemoveSlide(slide);
                targetPart.InsertSlideAfter(slide, target);
            }
        }
コード例 #11
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Duplicates the specified part and inserts the copy
        /// directly after the original slide in the same part (can be undone).
        /// </summary>
        /// <param name="slide">The slide to duplicate.</param>
        /// <returns>The created duplicate.</returns>
        public SongSlide DuplicateSlide(SongSlide slide)
        {
            SongSlide s;
            int       i = Slides.IndexOf(slide);

            using (Undo.ChangeFactory.Batch(this, "DuplicateSlide"))
            {
                s = slide.Copy();
                Undo.ChangeFactory.OnChanging(this,
                                              () => { slides.Remove(s); },
                                              () => { slides.Insert(i + 1, s); },
                                              "DuplicateSlide");
                slides.Insert(i + 1, s);
            }
            return(s);
        }
コード例 #12
0
ファイル: SongPart.cs プロジェクト: SolidStumbler/WordsLive
        /// <summary>
        /// Inserts a slide after a specified target slide in this part (can be undone).
        /// </summary>
        /// <param name="slide">The slide to insert.</param>
        /// <param name="target">The target slide. Must be contained in this part.</param>
        public void InsertSlideAfter(SongSlide slide, SongSlide target)
        {
            var index = Slides.IndexOf(target);

            if (index < 0)
            {
                throw new InvalidOperationException("Slide is not in this part.");
            }

            if (index >= Slides.Count - 1)
            {
                AddSlide(slide);
            }
            else
            {
                Undo.ChangeFactory.OnChanging(this,
                                              () => { slides.Remove(slide); },
                                              () => { slides.Insert(index + 1, slide); },
                                              "InsertSlideAfter");
                slides.Insert(index + 1, slide);
            }
        }
コード例 #13
0
        public void PartRemoveSlideDisconnected()
        {
            var slide1 = new SongSlide(song);

            Assert.Throws<InvalidOperationException>(() => part.RemoveSlide(slide1));
        }
コード例 #14
0
ファイル: Song.cs プロジェクト: Boddlnagg/WordsLive
		/// <summary>
		/// Moves a slide to another part (can be undone).
		/// </summary>
		/// <param name="slide">The slide to move.</param>
		/// <param name="target">The target part.</param>
		public void MoveSlide(SongSlide slide, SongPart target)
		{
			var part = FindPartWithSlide(slide);

			using (Undo.ChangeFactory.Batch(this, "MoveSlide"))
			{
				part.RemoveSlide(slide);
				target.AddSlide(slide);
			}
		}
コード例 #15
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
        /// <summary>
        /// Removes a specified slide from this part (can be undone).
        /// </summary>
        /// <param name="slide"></param>
        public void RemoveSlide(SongSlide slide)
        {
            if (slide == null)
                throw new ArgumentNullException("slide");

            if (Slides.Count <= 1)
                throw new InvalidOperationException("Can't remove last slide in a part.");

            int i = Slides.IndexOf(slide);
            if (i < 0)
                throw new InvalidOperationException("Slide is not in this part.");

            Undo.ChangeFactory.OnChanging(this,
                () => { slides.Insert(i, slide); },
                () => { slides.Remove(slide); },
                "RemoveSlide");
            slides.Remove(slide);
        }
コード例 #16
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
        /// <summary>
        /// Inserts a slide after a specified target slide in this part (can be undone).
        /// </summary>
        /// <param name="slide">The slide to insert.</param>
        /// <param name="target">The target slide. Must be contained in this part.</param>
        public void InsertSlideAfter(SongSlide slide, SongSlide target)
        {
            var index = Slides.IndexOf(target);
            if (index < 0)
                throw new InvalidOperationException("Slide is not in this part.");

            if (index >= Slides.Count - 1)
            {
                AddSlide(slide);
            }
            else
            {
                Undo.ChangeFactory.OnChanging(this,
                    () => { slides.Remove(slide); },
                    () => { slides.Insert(index + 1, slide); },
                    "InsertSlideAfter");
                slides.Insert(index + 1, slide);
            }
        }
コード例 #17
0
 public override void Init()
 {
     base.Init();
     part = song.Parts.Single();
     slide = part.Slides.Single();
 }
コード例 #18
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
 /// <summary>
 /// Duplicates the specified part and inserts the copy
 /// directly after the original slide in the same part (can be undone).
 /// </summary>
 /// <param name="slide">The slide to duplicate.</param>
 /// <returns>The created duplicate.</returns>
 public SongSlide DuplicateSlide(SongSlide slide)
 {
     SongSlide s;
     int i = Slides.IndexOf(slide);
     using (Undo.ChangeFactory.Batch(this, "DuplicateSlide"))
     {
         s = slide.Copy();
         Undo.ChangeFactory.OnChanging(this,
             () => { slides.Remove(s); },
             () => { slides.Insert(i + 1, s); },
             "DuplicateSlide");
         slides.Insert(i + 1, s);
     }
     return s;
 }
コード例 #19
0
ファイル: SongSlide.cs プロジェクト: Boddlnagg/WordsLive
 /// <summary>
 /// Copies this slide.
 /// </summary>
 /// <returns>A copy of this slide.</returns>
 public SongSlide Copy()
 {
     var s = new SongSlide(Root);
     s.Text = Text;
     s.Translation = Translation;
     s.BackgroundIndex = BackgroundIndex;
     s.Size = Size;
     return s;
 }
コード例 #20
0
ファイル: Song.cs プロジェクト: Boddlnagg/WordsLive
		/// <summary>
		/// Copies a slide and inserts it after another slide (can be undone).
		/// </summary>
		/// <param name="slide">The slide to copy</param>
		/// <param name="target">The slide after which the copy will be inserted.</param>
		/// <returns>The copy.</returns>
		public SongSlide CopySlideAfter(SongSlide slide, SongSlide target)
		{
			SongSlide s;
			var part = FindPartWithSlide(slide);
			var targetPart = FindPartWithSlide(target);

			using (Undo.ChangeFactory.Batch(this, "CopySlideAfter"))
			{
				s = slide.Copy();
				targetPart.InsertSlideAfter(s, target);
			}

			return s;
		}
コード例 #21
0
ファイル: Song.cs プロジェクト: Boddlnagg/WordsLive
		/// <summary>
		/// Moves a slide to the position directly after another slide (can be undone).
		/// </summary>
		/// <param name="slide">The slide to move.</param>
		/// <param name="target">The target slide.</param>
		public void MoveSlideAfter(SongSlide slide, SongSlide target)
		{
			if (slide == target)
				return;

			var part = FindPartWithSlide(slide);
			var targetPart = FindPartWithSlide(target);

			using (Undo.ChangeFactory.Batch(this, "MoveSlide"))
			{
				part.RemoveSlide(slide);
				targetPart.InsertSlideAfter(slide, target);
			}
		}
コード例 #22
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
 /// <summary>
 /// Splits a slide at a specified index. The first part remains in the original slide
 /// and the rest is moved to a new slide (can be undone).
 /// </summary>
 /// <param name="slide">The slide to split.</param>
 /// <param name="splitIndex">The index to split at.</param>
 /// <returns>A new slide containing the rest of the text after the split index.</returns>
 public SongSlide SplitSlide(SongSlide slide, int splitIndex)
 {
     SongSlide newSlide;
     using (Undo.ChangeFactory.Batch(this, "SplitSlide"))
     {
         var textBefore = slide.Text.Substring(0, splitIndex);
         if (textBefore.EndsWith("\r\n"))
             textBefore = textBefore.Substring(0, textBefore.Length - 2);
         else if (textBefore.EndsWith("\n"))
             textBefore = textBefore.Substring(0, textBefore.Length - 1);
         var textAfter = slide.Text.Substring(splitIndex);
         if (textAfter.StartsWith("\r\n"))
             textAfter = textAfter.Substring(2);
         else if (textAfter.StartsWith("\n"))
             textAfter = textAfter.Substring(1);
         newSlide = DuplicateSlide(slide);
         slide.Text = textBefore;
         newSlide.Text = textAfter;
     }
     return newSlide;
 }
コード例 #23
0
ファイル: Song.cs プロジェクト: SolidStumbler/WordsLive
 /// <summary>
 /// Finds the part that contains a given slide.
 /// </summary>
 /// <param name="slide">The slide. Slide instances must always be unique in a song structure.</param>
 /// <returns>The part that contains the slide.</returns>
 public SongPart FindPartWithSlide(SongSlide slide)
 {
     return(Parts.Where(p => p.Slides.Contains(slide)).SingleOrDefault());
 }
コード例 #24
0
ファイル: Song.cs プロジェクト: Boddlnagg/WordsLive
		/// <summary>
		/// Copies the specified slide into a given part.
		/// The copy will be appended to the part's slide list
		/// (can be undone).
		/// </summary>
		/// <param name="slide">The slide to copy.</param>
		/// <param name="target">The part where the copy will be inserted.</param>
		/// <returns>The copy.</returns>
		public SongSlide CopySlide(SongSlide slide, SongPart target)
		{
			SongSlide s;
			var part = FindPartWithSlide(slide);

			using (Undo.ChangeFactory.Batch(this, "CopySlide"))
			{
				s = slide.Copy();
				target.AddSlide(s);
			}

			return s;
		}
コード例 #25
0
ファイル: SongTests.cs プロジェクト: SolidStumbler/WordsLive
 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);
 }
コード例 #26
0
ファイル: Song.cs プロジェクト: Boddlnagg/WordsLive
		/// <summary>
		/// Finds the part that contains a given slide.
		/// </summary>
		/// <param name="slide">The slide. Slide instances must always be unique in a song structure.</param>
		/// <returns>The part that contains the slide.</returns>
		public SongPart FindPartWithSlide(SongSlide slide)
		{
			return Parts.Where(p => p.Slides.Contains(slide)).SingleOrDefault();
		}
コード例 #27
0
 public void PartInsertSlideAfterUndoRedo()
 {
     var slide0 = part.Slides.Single();
     var slide1 = new SongSlide(song);
     var slide2 = new SongSlide(song);
     part.AddSlide(slide1);
     ClearUndoRedoStack();
     part.InsertSlideAfter(slide2, slide0);
     Assert.Equal(3, part.Slides.Count);
     Assert.Same(slide0, part.Slides[0]);
     Assert.Same(slide2, part.Slides[1]);
     Assert.Same(slide1, part.Slides[2]);
     Assert.Equal(1, UndoStackSize);
     Undo();
     Assert.Equal(2, part.Slides.Count);
     Redo();
     Assert.Equal(3, part.Slides.Count);
 }
コード例 #28
0
        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) + ")");
        }
コード例 #29
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
        /// <summary>
        /// Adds an empty slide to the part (can be undone).
        /// </summary>
        /// <returns>The newly created slide.</returns>
        public SongSlide AddSlide()
        {
            SongSlide slide;

            slide = new SongSlide(Root);
            AddSlide(slide);

            return slide;
        }
コード例 #30
0
ファイル: SongTests.cs プロジェクト: SolidStumbler/WordsLive
        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);
        }
コード例 #31
0
ファイル: SongPart.cs プロジェクト: Boddlnagg/WordsLive
 /// <summary>
 /// Adds an existing slide to this part (can be undone).
 /// </summary>
 /// <param name="slide">The slide to add.</param>
 public void AddSlide(SongSlide slide)
 {
     Undo.ChangeFactory.OnChanging(this,
         () => { slides.Remove(slide); },
         () => { slides.Add(slide); },
         "AddSlide");
     slides.Add(slide);
 }
コード例 #32
0
ファイル: SongTests.cs プロジェクト: SolidStumbler/WordsLive
        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);
        }
コード例 #33
0
 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));
 }