// 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
{
///
/// Description of the pad content
///
public class DefinitionViewPad : AbstractPadContent
{
AvalonEdit.TextEditor ctl;
///
/// The control representing the pad
///
public override object Control {
get {
return ctl;
}
}
///
/// Creates a new DefinitionViewPad object
///
public DefinitionViewPad()
{
ctl = Editor.AvalonEdit.AvalonEditTextEditorAdapter.CreateAvalonEditInstance();
ctl.IsReadOnly = true;
ctl.MouseDoubleClick += OnDoubleClick;
throw new NotImplementedException();
//ParserService.ParserUpdateStepFinished += OnParserUpdateStep;
ctl.IsVisibleChanged += delegate { UpdateTick(null); };
}
///
/// Cleans up all used resources
///
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 ResolveAtCaretAsync(ParserUpdateStepEventArgs e)
{
IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
if (window == null)
return Task.FromResult(null);
IViewContent viewContent = window.ActiveViewContent;
if (viewContent == null)
return Task.FromResult(null);
ITextEditor editor = viewContent.GetService();
if (editor == null)
return Task.FromResult(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(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);
}
}
///
/// Loads the file from the corresponding text editor window if it is
/// open otherwise the file is loaded from the file system.
///
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));
}
}
}