// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Debugger;
using Debugger.AddIn;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Project;
using Exception = System.Exception;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public class WatchPad : DebuggerPad
{
WatchList watchList;
Process debuggedProcess;
static WatchPad instance;
/// Always check if Instance is null, might be null if pad is not opened!
public static WatchPad Instance {
get { return instance; }
}
public WatchPad()
{
instance = this;
}
///
/// This is not used anywhere, but it is neccessary to be overridden in children of AbstractPadContent.
///
public override object Control {
get {
return watchList;
}
}
public Process Process {
get { return debuggedProcess; }
}
protected override void InitializeComponents()
{
watchList = new WatchList();
watchList.MouseDoubleClick += watchList_DoubleClick;
watchList.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu");
watchList.AllowDrop = true;
watchList.DragEnter += watchList_DragOver;
watchList.Drop += watchList_Drop;
watchList.KeyUp += watchList_KeyUp;
}
void watchList_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete) {
RemoveWatchCommand cmd = new RemoveWatchCommand { Owner = this };
cmd.Run();
}
}
void watchList_Drop(object sender, DragEventArgs e)
{
if (ProjectService.CurrentProject == null) return;
if (e.Data == null) return;
if (!e.Data.GetDataPresent(DataFormats.StringFormat)) return;
if (string.IsNullOrEmpty(e.Data.GetData(DataFormats.StringFormat).ToString())) return;
string language = ProjectService.CurrentProject.Language;
// FIXME languages
TextNode text = new TextNode(e.Data.GetData(DataFormats.StringFormat).ToString(),
language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp);
if (!watchList.WatchItems.Contains(text))
watchList.WatchItems.ContainsItem(text);
this.RefreshPad();
}
void watchList_DragOver(object sender, DragEventArgs e)
{
if(e.Data.GetDataPresent(DataFormats.StringFormat)) {
e.Effects = DragDropEffects.Copy;
}
else {
e.Effects = DragDropEffects.None;
e.Handled = true;
}
}
void watchList_DoubleClick(object sender, MouseEventArgs e)
{
if (watchList.SelectedNode == null)
{
AddWatchCommand command = new AddWatchCommand { Owner = this };
command.Run();
}
}
void ResetPad(object sender, EventArgs e)
{
string language = ProjectService.CurrentProject.Language;
// rebuild list
var nodes = new List();
foreach (var nod in watchList.WatchItems)
nodes.Add(new TextNode(nod.Name,
language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp));
watchList.WatchItems.Clear();
foreach (var nod in nodes)
watchList.WatchItems.Add(nod);
}
protected override void SelectProcess(Process process)
{
if (debuggedProcess != null) {
debuggedProcess.Paused -= debuggedProcess_Paused;
debuggedProcess.Exited -= ResetPad;
}
debuggedProcess = process;
if (debuggedProcess != null) {
debuggedProcess.Paused += debuggedProcess_Paused;
debuggedProcess.Exited += ResetPad;
}
RefreshPad();
}
void debuggedProcess_Paused(object sender, ProcessEventArgs e)
{
RefreshPad();
}
public override void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null)
return;
using(new PrintTimes("Watch Pad refresh")) {
try {
Utils.DoEvents(debuggedProcess);
List nodes = new List();
foreach (var nod in watchList.WatchItems) {
try {
LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(nod.Name) ? "is null or empty!" : nod.Name));
var nodExpression = debugger.GetExpression(nod.Name);
//Value val = ExpressionEvaluator.Evaluate(nod.Name, nod.Language, debuggedProcess.SelectedStackFrame);
ExpressionNode valNode = new ExpressionNode(null, nod.Name, nodExpression);
nodes.Add(valNode);
}
catch (GetValueException) {
string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), nod.Name);
ErrorInfoNode infoNode = new ErrorInfoNode(nod.Name, error);
nodes.Add(infoNode);
}
}
// rebuild list
watchList.WatchItems.Clear();
foreach (var nod in nodes)
watchList.WatchItems.Add(nod);
}
catch(AbortedBecauseDebuggeeResumedException) { }
catch(Exception ex) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
MessageService.ShowException(ex);
}
}
}
}
}
}