#region Using Directives using System; using System.ComponentModel; using System.Windows.Forms; #endregion Using Directives namespace ScintillaNET { /// /// Manages Document Navigation, which is a snapshot history of movements within /// a document. /// [TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))] public class DocumentNavigation : TopLevelHelper { #region Fields private bool _supressNext = false; private Timer t = null; private int _navigationPointTimeout = 200; public FakeStack _forewardStack = new FakeStack(); public FakeStack _backwardStack = new FakeStack(); private int _maxHistorySize = 50; private bool _isEnabled = true; #endregion Fields #region Methods /// /// Causes the current position to navigate to the last snapshotted document position. /// public void NavigateBackward() { if (_backwardStack.Count == 0) return; int currentPos = Scintilla.Caret.Position; if (currentPos == _backwardStack.Current.Start && _backwardStack.Count == 1) return; int pos = _backwardStack.Pop().Start; if (pos != currentPos) { _forewardStack.Push(NewRange(currentPos)); Scintilla.Caret.Goto(pos); } else { _forewardStack.Push(NewRange(pos)); Scintilla.Caret.Goto(_backwardStack.Current.Start); } _supressNext = true; } /// /// After 1 or more backwards navigations this command navigates to the previous /// backwards navigation point. /// public void NavigateForward() { if (!CanNavigateForward) return; int pos = _forewardStack.Pop().Start; _backwardStack.Push(NewRange(pos)); Scintilla.Caret.Goto(pos); _supressNext = true; } private NavigationPont NewRange(int pos) { NavigationPont mr = new NavigationPont(pos, Scintilla); Scintilla.ManagedRanges.Add(mr); return mr; } public void Reset() { _backwardStack.Clear(); _forewardStack.Clear(); ResetIsEnabled(); ResetMaxHistorySize(); } private void ResetIsEnabled() { _isEnabled = true; } private void ResetMaxHistorySize() { _maxHistorySize = 50; } private void ResetNavigationPointTimeout() { _navigationPointTimeout = 200; } private void scintilla_SelectionChanged(object sender, EventArgs e) { if (!_isEnabled) return; if (!_supressNext) { t.Enabled = false; t.Enabled = true; } else { _supressNext = false; } } internal bool ShouldSerialize() { return ShouldSerializeIsEnabled() || ShouldSerializeMaxHistorySize(); } private bool ShouldSerializeIsEnabled() { return !_isEnabled; } private bool ShouldSerializeMaxHistorySize() { return _maxHistorySize != 50; } private bool ShouldSerializeNavigationPointTimeout() { return _navigationPointTimeout != 200; } private void t_Tick(object sender, EventArgs e) { t.Enabled = false; int pos = NativeScintilla.GetCurrentPos(); if ((_forewardStack.Count == 0 || _forewardStack.Current.Start != pos) && (_backwardStack.Count == 0 || _backwardStack.Current.Start != pos)) _backwardStack.Push(NewRange(pos)); } #endregion Methods #region Properties /// /// List of entries that allow you to navigate backwards. /// /// /// The ForwardStack and BackwardStack can be shared between multiple /// ScintillaNET objects. This is useful in MDI applications when you wish /// to have a shared document navigation that remembers positions in each /// document. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FakeStack BackwardStack { get { return _backwardStack; } set { _backwardStack = value; } } /// /// Returns true if ScintillaNET can perform a successful backward navigation. /// [Browsable(false)] public bool CanNavigateBackward { get { if (_backwardStack.Count == 0 || (NativeScintilla.GetCurrentPos() == _backwardStack.Current.Start && _backwardStack.Count == 1)) return false; return true; } } /// /// Returns true if ScintillaNET can perform a successful forward navigation. /// [Browsable(false)] public bool CanNavigateForward { get { return _forewardStack.Count > 0; } } /// /// List of entries that allow you to navigate forwards. /// /// /// The ForwardStack and BackwardStack can be shared between multiple /// ScintillaNET objects. This is useful in MDI applications when you wish /// to have a shared document navigation that remembers positions in each /// document. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FakeStack ForewardStack { get { return _forewardStack; } set { _forewardStack = value; } } /// /// Gets/Sets whether Document Navigation is tracked. Defaults to true. /// public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; } } /// /// Maximum number of places the document navigation remembers. Defaults to 50. /// /// /// When the max value is reached the oldest entries are removed. /// public int MaxHistorySize { get { return _maxHistorySize; } set { _maxHistorySize = value; _backwardStack.MaxCount = value; _forewardStack.MaxCount = value; } } /// /// Time in milliseconds to wait before a Navigation Point is set. Default is 200 /// /// /// In text editing, the current caret position is constantly changing. Rather than capture every /// change in position, ScintillaNET captures the current position [NavigationPointTimeout]ms after a /// position changes, only then is it eligable for another snapshot /// public int NavigationPointTimeout { get { return _navigationPointTimeout; } set { _navigationPointTimeout = value; } } #endregion Properties #region Constructors internal DocumentNavigation(Scintilla scintilla) : base(scintilla) { t = new Timer(); t.Interval = _navigationPointTimeout; t.Tick += new EventHandler(t_Tick); scintilla.SelectionChanged += new EventHandler(scintilla_SelectionChanged); } #endregion Constructors } }