Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
using System;
using System.Collections.Generic;
using OpenScadGraphEditor.Library;
namespace OpenScadGraphEditor.History
{
/// <summary>
/// This class is responsible for managing Undo/Redo history.
/// </summary>
public class HistoryStack
{
private readonly List<HistoryStackItem> _history = new List<HistoryStackItem>();
private int _currentIndex;
public HistoryStack(ScadProject initialProjectState, EditorState initialEditorState)
{
// make a history item for the initial state
var initialHistoryItem = new HistoryStackItem("", initialProjectState.Save(), initialEditorState);
_history.Add(initialHistoryItem);
_currentIndex = 0;
}
/// <summary>
/// Adds a snapshot to the history.
/// </summary>
public void AddSnapshot(string operationName, ScadProject project, EditorState editorState )
{
var savedProject = project.Save();
// create a history stack item
var item = new HistoryStackItem(operationName, savedProject, editorState);
// remove all history states after the current one (if you have redo steps they will now be overwritten
// by a new timeline.
if (_history.Count > _currentIndex + 1)
{
_history.RemoveRange(_currentIndex + 1, _history.Count - _currentIndex - 1);
}
// add it to the history
_history.Add(item);
// set the current index to the new item
_currentIndex++;
}
public HistoryStackItem Peek()
{
return _history[_currentIndex];
}
/// <summary>
/// Drops the last history item and restores the state of the item that is now on top.
/// </summary>
public EditorState Undo(ScadProject project)
{
// we need at least 2 items in the history stack
if (_currentIndex < 1)
{
throw new InvalidOperationException("Cannot undo. History stack is empty.");
}
var item = _history[_currentIndex - 1];
// restore the project
project.Load(item.ProjectState, project.ProjectPath);
_currentIndex--;
return item.EditorState;
}
/// <summary>
/// Moves the top of the stack to the next item and restores the state of the item that is now on top.
/// </summary>
public EditorState Redo(ScadProject project)
{
// we need at least one item past the current index in the history stack
if (_currentIndex >= _history.Count - 1)
{
throw new InvalidOperationException("Cannot redo. History has no more redo steps left.");
}
var item = _history[_currentIndex + 1];
// restore the project
project.Load(item.ProjectState, project.ProjectPath);
_currentIndex++;
return item.EditorState;
}
/// <summary>
/// Checks if currently an undo step is available.
/// </summary>
public bool CanUndo(out string operationName)
{
// and undo step is available if we have at least two items in the history stack
if (_currentIndex < 1)
{
operationName = "<no more undo steps>";
return false;
}
operationName = _history[_currentIndex].OperationName;
return true;
}
/// <summary>
/// Checks if currently a redo step is available.
/// </summary>
public bool CanRedo(out string operationName)
{
// and redo step is available if we have at least one item past the current index in the history stack
if (_currentIndex >= _history.Count - 1)
{
operationName = "<no more redo steps>";
return false;
}
operationName = _history[_currentIndex + 1].OperationName;
return true;
}
}
}7951eb9aaThis file is pinned to the selected release. Download the original to open it in your design tool.