You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.0 KiB
135 lines
4.0 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) |
|
|
|
using System; |
|
using System.IO; |
|
using System.Windows; |
|
using System.Threading.Tasks; |
|
using ICSharpCode.AvalonEdit; |
|
using ICSharpCode.AvalonEdit.Document; |
|
using ICSharpCode.AvalonEdit.Highlighting; |
|
using ICSharpCode.Core; |
|
using ICSharpCode.NRefactory.Semantics; |
|
using ICSharpCode.NRefactory.TypeSystem; |
|
using ICSharpCode.SharpDevelop.Editor; |
|
using ICSharpCode.SharpDevelop.Parser; |
|
|
|
namespace ICSharpCode.SharpDevelop.Gui |
|
{ |
|
/// <summary> |
|
/// Description of the pad content |
|
/// </summary> |
|
public class DefinitionViewPad : AbstractPadContent |
|
{ |
|
AvalonEdit.TextEditor ctl; |
|
|
|
/// <summary> |
|
/// The control representing the pad |
|
/// </summary> |
|
public override object Control { |
|
get { |
|
return ctl; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Creates a new DefinitionViewPad object |
|
/// </summary> |
|
public DefinitionViewPad() |
|
{ |
|
ctl = Editor.AvalonEdit.AvalonEditTextEditorAdapter.CreateAvalonEditInstance(); |
|
ctl.IsReadOnly = true; |
|
ctl.MouseDoubleClick += OnDoubleClick; |
|
throw new NotImplementedException(); |
|
//ParserService.ParserUpdateStepFinished += OnParserUpdateStep; |
|
ctl.IsVisibleChanged += delegate { UpdateTick(null); }; |
|
} |
|
|
|
/// <summary> |
|
/// Cleans up all used resources |
|
/// </summary> |
|
public override void Dispose() |
|
{ |
|
//ParserService.ParserUpdateStepFinished -= OnParserUpdateStep; |
|
ctl.Document = null; |
|
base.Dispose(); |
|
} |
|
|
|
void OnDoubleClick(object sender, EventArgs e) |
|
{ |
|
string fileName = currentFileName; |
|
if (fileName != null) { |
|
var caret = ctl.TextArea.Caret; |
|
FileService.JumpToFilePosition(fileName, caret.Line, caret.Column); |
|
|
|
// refresh DefinitionView to show the definition of the expression that was double-clicked |
|
UpdateTick(null); |
|
} |
|
} |
|
|
|
void OnParserUpdateStep(object sender, ParserUpdateStepEventArgs e) |
|
{ |
|
UpdateTick(e); |
|
} |
|
|
|
async void UpdateTick(ParserUpdateStepEventArgs e) |
|
{ |
|
if (!ctl.IsVisible) return; |
|
LoggingService.Debug("DefinitionViewPad.Update"); |
|
|
|
ResolveResult res = await ResolveAtCaretAsync(e); |
|
if (res == null) return; |
|
var pos = res.GetDefinitionRegion(); |
|
if (pos.IsEmpty) return; |
|
OpenFile(pos); |
|
} |
|
|
|
Task<ResolveResult> ResolveAtCaretAsync(ParserUpdateStepEventArgs e) |
|
{ |
|
IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow; |
|
if (window == null) |
|
return Task.FromResult<ResolveResult>(null); |
|
IViewContent viewContent = window.ActiveViewContent; |
|
if (viewContent == null) |
|
return Task.FromResult<ResolveResult>(null); |
|
ITextEditor editor = viewContent.GetService<ITextEditor>(); |
|
if (editor == null) |
|
return Task.FromResult<ResolveResult>(null); |
|
|
|
// e might be null when this is a manually triggered update |
|
// don't resolve when an unrelated file was changed |
|
if (e != null && editor.FileName != e.FileName) |
|
return Task.FromResult<ResolveResult>(null); |
|
|
|
return SD.ParserService.ResolveAsync(editor.FileName, editor.Caret.Location, editor.Document); |
|
} |
|
|
|
DomRegion oldPosition; |
|
string currentFileName; |
|
|
|
void OpenFile(DomRegion pos) |
|
{ |
|
if (pos.Equals(oldPosition)) return; |
|
oldPosition = pos; |
|
if (pos.FileName != currentFileName) |
|
LoadFile(pos.FileName); |
|
ctl.TextArea.Caret.Location = pos.Begin; |
|
Rect r = ctl.TextArea.Caret.CalculateCaretRectangle(); |
|
if (!r.IsEmpty) { |
|
ctl.ScrollToVerticalOffset(r.Top - 4); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Loads the file from the corresponding text editor window if it is |
|
/// open otherwise the file is loaded from the file system. |
|
/// </summary> |
|
void LoadFile(string fileName) |
|
{ |
|
// Load the text into the definition view's text editor. |
|
ctl.Document = new TextDocument(SD.FileService.GetFileContent(fileName), fileName); |
|
currentFileName = fileName; |
|
ctl.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(fileName)); |
|
} |
|
} |
|
}
|
|
|