public override DataTemplate SelectTemplate(object item, DependencyObject container) { ISongElement element = (ISongElement)item; if (element is SongSlide) { return(EditTextWithTranslationTemplate); } else if (element is Nodes.CategoryNode) { return(EditCategoryTemplate); } else if (element is Nodes.CopyrightNode) { return(EditCopyrightTemplate); } else if (element is Nodes.SourceNode) { return(EditSourceTemplate); } else if (element is Nodes.LanguageNode) { return(EditLanguageTemlate); } else if (element is Nodes.CcliNumberNode) { return(EditCcliNumberTemplate); } else { return(EmptyTemplate); } }
private void GridCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { ISongElement node = StructureTree.SelectedItem as ISongElement; if (e.Command == ApplicationCommands.Undo) { e.CanExecute = song.UndoManager.CanUndo; } else if (e.Command == ApplicationCommands.Redo) { e.CanExecute = song.UndoManager.CanRedo; } else if (e.Command == CustomCommands.Split) { if (node is SongSlide) { // get selection length var content = (ContentControl)EditBorder.Child; var tpl = (content.ContentTemplateSelector as EditControlTemplateSelector).EditTextWithTranslationTemplate; var tb = tpl.FindName("TextTextBox", content.FindVisualChild <ContentPresenter>()) as TextBox; if (tb != null) { e.CanExecute = (tb.SelectionLength == 0); } } } else if (e.Command == CustomCommands.ChooseBackground) { e.CanExecute = node is Song || node is SongPart || node is SongSlide; } e.Handled = true; }
public static IDisposable Batch(ISongElement instance, string description) { if (instance.Root.IsUndoEnabled) return new UndoBatch(instance.Root.UndoManager.Root, description, false); else return new UndoBatchDummy(); }
private void GridCommand_Executed(object sender, ExecutedRoutedEventArgs e) { ISongElement node = StructureTree.SelectedItem as ISongElement; if (e.Command == ApplicationCommands.Undo) { song.UndoManager.Undo(); } else if (e.Command == ApplicationCommands.Redo) { song.UndoManager.Redo(); } else if (e.Command == CustomCommands.Split) { // get text cursor position var content = (ContentControl)EditBorder.Child; var tpl = (content.ContentTemplateSelector as EditControlTemplateSelector).EditTextWithTranslationTemplate; var tb = tpl.FindName("TextTextBox", content.FindVisualChild <ContentPresenter>()) as TextBox; var newSlide = song.FindPartWithSlide(node as SongSlide).SplitSlide(node as SongSlide, tb.SelectionStart); } else if (e.Command == CustomCommands.ChooseBackground) { ChooseBackground(node); } e.Handled = true; }
/// <summary> /// Construct a Change instance with actions for undo / redo. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> /// <param name="descriptionOfChange">A description of this change.</param> public static void OnChanging(ISongElement instance, string propertyName, object oldValue, object newValue, string descriptionOfChange) { if (!instance.Root.IsUndoEnabled) return; Change change = GetChange(instance, propertyName, oldValue, newValue); instance.Root.UndoManager.Root.AddChange(change, descriptionOfChange); }
/// <summary> /// Construct a Change instance with actions for undo / redo. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> /// <returns>A Change that can be added to the UndoRoot's undo stack.</returns> public static Change GetChange(ISongElement instance, string propertyName, object oldValue, object newValue) { var change = new DelegateChange(instance, () => instance.GetType().GetProperty(propertyName).SetValue(instance, oldValue, null), () => instance.GetType().GetProperty(propertyName).SetValue(instance, newValue, null), new ChangeKey <object, string>(instance, propertyName) ); return(change); }
/// <summary> /// Construct a Change instance with actions for undo / redo. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> /// <returns>A Change that can be added to the UndoRoot's undo stack.</returns> public static Change GetChange(ISongElement instance, string propertyName, object oldValue, object newValue) { var change = new DelegateChange(instance, () => instance.GetType().GetProperty(propertyName).SetValue(instance, oldValue, null), () => instance.GetType().GetProperty(propertyName).SetValue(instance, newValue, null), new ChangeKey<object, string>(instance, propertyName) ); return change; }
public static void OnChanging(ISongElement instance, Action undoAction, Action redoAction, string description) { if (!instance.Root.IsUndoEnabled) { return; } var ch = new DelegateChange(instance, undoAction, redoAction, new ChangeKey <object, string>(instance, description)); instance.Root.UndoManager.Root.AddChange(ch, description); }
/// <summary> /// Construct a Change instance with actions for undo / redo. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> /// <param name="descriptionOfChange">A description of this change.</param> public static void OnChanging(ISongElement instance, string propertyName, object oldValue, object newValue, string descriptionOfChange) { if (!instance.Root.IsUndoEnabled) { return; } Change change = GetChange(instance, propertyName, oldValue, newValue); instance.Root.UndoManager.Root.AddChange(change, descriptionOfChange); }
public static IDisposable Batch(ISongElement instance, string description) { if (instance.Root.IsUndoEnabled) { return(new UndoBatch(instance.Root.UndoManager.Root, description, false)); } else { return(new UndoBatchDummy()); } }
/// <summary> /// Construct a Change instance with actions for undo / redo /// and tries to merge it with the previous one if possible. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> public static void OnChangingTryMerge(ISongElement instance, string propertyName, object oldValue, object newValue) { if (!instance.Root.IsUndoEnabled) { return; } var ch = DefaultChangeFactory.Current.GetChange(instance, propertyName, oldValue, newValue); var x = ch.ChangeKey.GetType(); if (instance.Root.IsModified && instance.Root.UndoManager.Root.UndoStack.Count() > 0 && instance.Root.UndoManager.Root.UndoStack.First().Changes.Count() > 0 && instance.Root.UndoManager.Root.UndoStack.First().Changes.First().Target == instance && instance.Root.UndoManager.Root.UndoStack.First().Changes.Count() == 1 && ((ChangeKey <object, string>)instance.Root.UndoManager.Root.UndoStack.First().Changes.First().ChangeKey).Item2 == propertyName) { instance.Root.UndoManager.Root.UndoStack.First().Changes.First().MergeWith(ch); } else { instance.Root.UndoManager.Root.AddChange(ch, propertyName); } }
public static void OnChanging(ISongElement instance, Action undoAction, Action redoAction, string description) { if (!instance.Root.IsUndoEnabled) return; var ch = new DelegateChange(instance, undoAction, redoAction, new ChangeKey<object, string>(instance, description)); instance.Root.UndoManager.Root.AddChange(ch, description); }
private void ChooseBackground(ISongElement element) { SongBackground bg = null; if (element is SongSlide) bg = (element as SongSlide).Background; else if (element is SongPart) bg = (element as SongPart).Slides[0].Background; else if (element is Song) bg = element.Root.FirstSlide != null ? element.Root.FirstSlide.Background : element.Root.Backgrounds[0]; else throw new ArgumentException("element must be either Song, SongPart or SongSlide."); var win = new ChooseBackgroundWindow(bg, element is Song); win.Owner = this.FindVisualParent<Window>(); win.ShowDialog(); if (win.DialogResult.HasValue && win.DialogResult.Value) { if (element is Song || win.ApplyToAllSlides) { var song = element.Root; song.SetBackground(win.ChosenBackground); // this needs to be called manually, because the preview can not listen to background changes // when the root node is selected this.PreviewControl.Update(); } else if (element is SongPart) { var part = element as SongPart; // only set background if it is different var bgs = part.Slides.Select(s => s.Background).Distinct(); if (bgs.Count() != 1 || !bgs.First().Equals(win.ChosenBackground)) { if (win.ChosenBackground.Type == SongBackgroundType.Video) { var res = MessageBox.Show(Resource.eMsgVideoBackgroundForElement, Resource.eMsgVideoBackgroundForElementTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) part.Root.SetBackground(win.ChosenBackground); } else if (part.Root.VideoBackground != null) { var res = MessageBox.Show(Resource.eMsgReplaceVideoBackground, Resource.eMsgReplaceVideoBackgroundTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) part.Root.SetBackground(win.ChosenBackground); } else { part.SetBackground(win.ChosenBackground); } } } else if (element is SongSlide) { var slide = element as SongSlide; if (!slide.Background.Equals(win.ChosenBackground)) { if (win.ChosenBackground.Type == SongBackgroundType.Video) { var res = MessageBox.Show(Resource.eMsgVideoBackgroundForElement, Resource.eMsgVideoBackgroundForElementTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) slide.Root.SetBackground(win.ChosenBackground); } else if (slide.Root.VideoBackground != null) { var res = MessageBox.Show(Resource.eMsgReplaceVideoBackground, Resource.eMsgReplaceVideoBackgroundTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) slide.Root.SetBackground(win.ChosenBackground); } else { slide.SetBackground(win.ChosenBackground); } } } } }
/// <summary> /// Construct a Change instance with actions for undo / redo. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> public static void OnChanging(ISongElement instance, string propertyName, object oldValue, object newValue) { OnChanging(instance, propertyName, oldValue, newValue, propertyName); }
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); } }
/// <summary> /// Construct a Change instance with actions for undo / redo /// and tries to merge it with the previous one if possible. /// </summary> /// <param name="instance">The instance that changed.</param> /// <param name="propertyName">The property name that changed. (Case sensitive, used by reflection.)</param> /// <param name="oldValue">The old value of the property.</param> /// <param name="newValue">The new value of the property.</param> public static void OnChangingTryMerge(ISongElement instance, string propertyName, object oldValue, object newValue) { if (!instance.Root.IsUndoEnabled) return; var ch = DefaultChangeFactory.Current.GetChange(instance, propertyName, oldValue, newValue); var x = ch.ChangeKey.GetType(); if (instance.Root.IsModified && instance.Root.UndoManager.Root.UndoStack.Count() > 0 && instance.Root.UndoManager.Root.UndoStack.First().Changes.Count() > 0 && instance.Root.UndoManager.Root.UndoStack.First().Changes.First().Target == instance && instance.Root.UndoManager.Root.UndoStack.First().Changes.Count() == 1 && ((ChangeKey<object, string>)instance.Root.UndoManager.Root.UndoStack.First().Changes.First().ChangeKey).Item2 == propertyName) { instance.Root.UndoManager.Root.UndoStack.First().Changes.First().MergeWith(ch); } else { instance.Root.UndoManager.Root.AddChange(ch, propertyName); } }
private void ChooseBackground(ISongElement element) { SongBackground bg = null; if (element is SongSlide) { bg = (element as SongSlide).Background; } else if (element is SongPart) { bg = (element as SongPart).Slides[0].Background; } else if (element is Song) { bg = element.Root.FirstSlide != null ? element.Root.FirstSlide.Background : element.Root.Backgrounds[0]; } else { throw new ArgumentException("element must be either Song, SongPart or SongSlide."); } var win = new ChooseBackgroundWindow(bg, element is Song); win.Owner = this.FindVisualParent <Window>(); win.ShowDialog(); if (win.DialogResult.HasValue && win.DialogResult.Value) { if (element is Song || win.ApplyToAllSlides) { var song = element.Root; song.SetBackground(win.ChosenBackground); // this needs to be called manually, because the preview can not listen to background changes // when the root node is selected this.PreviewControl.Update(); } else if (element is SongPart) { var part = element as SongPart; // only set background if it is different var bgs = part.Slides.Select(s => s.Background).Distinct(); if (bgs.Count() != 1 || !bgs.First().Equals(win.ChosenBackground)) { if (win.ChosenBackground.Type == SongBackgroundType.Video) { var res = MessageBox.Show(Resource.eMsgVideoBackgroundForElement, Resource.eMsgVideoBackgroundForElementTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) { part.Root.SetBackground(win.ChosenBackground); } } else if (part.Root.VideoBackground != null) { var res = MessageBox.Show(Resource.eMsgReplaceVideoBackground, Resource.eMsgReplaceVideoBackgroundTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) { part.Root.SetBackground(win.ChosenBackground); } } else { part.SetBackground(win.ChosenBackground); } } } else if (element is SongSlide) { var slide = element as SongSlide; if (!slide.Background.Equals(win.ChosenBackground)) { if (win.ChosenBackground.Type == SongBackgroundType.Video) { var res = MessageBox.Show(Resource.eMsgVideoBackgroundForElement, Resource.eMsgVideoBackgroundForElementTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) { slide.Root.SetBackground(win.ChosenBackground); } } else if (slide.Root.VideoBackground != null) { var res = MessageBox.Show(Resource.eMsgReplaceVideoBackground, Resource.eMsgReplaceVideoBackgroundTitle, MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) { slide.Root.SetBackground(win.ChosenBackground); } } else { slide.SetBackground(win.ChosenBackground); } } } } }