8 changed files with 151 additions and 323 deletions
@ -1,66 +0,0 @@
@@ -1,66 +0,0 @@
|
||||
// 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.Collections; |
||||
using System.Dynamic; |
||||
using System.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using Debugger; |
||||
using Debugger.AddIn.Pads.ParallelPad; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public partial class RunningThreadsPad |
||||
{ |
||||
ContextMenu CreateContextMenuStrip() |
||||
{ |
||||
ContextMenu menu = new ContextMenu(); |
||||
menu.Opened += FillContextMenuStrip; |
||||
return menu; |
||||
} |
||||
|
||||
void FillContextMenuStrip(object sender, RoutedEventArgs e) |
||||
{ |
||||
var items = runningThreadsList.SelectedItems; |
||||
if (items == null || items.Count == 0) { |
||||
e.Handled = true; |
||||
return; |
||||
} |
||||
|
||||
ThreadModel item = items[0] as ThreadModel; |
||||
if (item == null) |
||||
return; |
||||
|
||||
ContextMenu menu = sender as ContextMenu; |
||||
menu.Items.Clear(); |
||||
|
||||
MenuItem freezeItem; |
||||
freezeItem = new MenuItem(); |
||||
freezeItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Freeze"); |
||||
freezeItem.IsChecked = item.Thread.Suspended; |
||||
freezeItem.Click += |
||||
delegate { |
||||
if (items == null || items.Count == 0) { |
||||
e.Handled = true; |
||||
return; |
||||
} |
||||
bool suspended = item.Thread.Suspended; |
||||
|
||||
if (WindowsDebugger.CurrentProcess == null || WindowsDebugger.CurrentProcess.IsRunning) { |
||||
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotFreezeWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.Freeze}"); |
||||
return; |
||||
} |
||||
|
||||
foreach(ThreadModel current in items.OfType<ThreadModel>()) { |
||||
current.Thread.Suspended = !suspended; |
||||
} |
||||
WindowsDebugger.RefreshPads(); |
||||
}; |
||||
|
||||
menu.Items.Add(freezeItem); |
||||
} |
||||
} |
||||
} |
||||
@ -1,145 +0,0 @@
@@ -1,145 +0,0 @@
|
||||
// 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.ObjectModel; |
||||
using System.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Threading; |
||||
using Debugger; |
||||
using Debugger.AddIn.Pads.Controls; |
||||
using Debugger.AddIn.Pads.ParallelPad; |
||||
using Debugger.AddIn.TreeModel; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Services; |
||||
using Exception = System.Exception; |
||||
using Thread = Debugger.Thread; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public partial class RunningThreadsPad : AbstractPadContent |
||||
{ |
||||
DockPanel panel; |
||||
ListView runningThreadsList; |
||||
ObservableCollection<ThreadModel> runningThreads; |
||||
|
||||
public override object Control { |
||||
get { return panel; } |
||||
} |
||||
|
||||
public RunningThreadsPad() |
||||
{ |
||||
this.panel = new DockPanel(); |
||||
runningThreads = new ObservableCollection<ThreadModel>(); |
||||
runningThreadsList = new ListView(); |
||||
runningThreadsList.ContextMenu = CreateContextMenuStrip(); |
||||
runningThreadsList.MouseDoubleClick += RunningThreadsListItemActivate; |
||||
runningThreadsList.ItemsSource = runningThreads; |
||||
runningThreadsList.View = new GridView(); |
||||
panel.Children.Add(runningThreadsList); |
||||
|
||||
RedrawContent(); |
||||
ResourceService.LanguageChanged += delegate { RedrawContent(); }; |
||||
|
||||
WindowsDebugger.RefreshingPads += RefreshPad; |
||||
RefreshPad(); |
||||
} |
||||
|
||||
public void RedrawContent() |
||||
{ |
||||
runningThreadsList.ClearColumns(); |
||||
runningThreadsList.AddColumn(ResourceService.GetString("Global.ID"), |
||||
new Binding { Path = new PropertyPath("ID") }, |
||||
100); |
||||
runningThreadsList.AddColumn(ResourceService.GetString("Global.Name"), |
||||
new Binding { Path = new PropertyPath("Name") }, |
||||
300); |
||||
runningThreadsList.AddColumn(ResourceService.GetString("AddIns.HtmlHelp2.Location"), |
||||
new Binding { Path = new PropertyPath("Location") }, |
||||
250); |
||||
runningThreadsList.AddColumn(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority"), |
||||
new Binding { Path = new PropertyPath("Priority") }, |
||||
120); |
||||
runningThreadsList.AddColumn(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Frozen"), |
||||
new Binding { Path = new PropertyPath("Frozen") }, |
||||
80); |
||||
} |
||||
|
||||
protected void RefreshPad() |
||||
{ |
||||
Process process = WindowsDebugger.CurrentProcess; |
||||
|
||||
if (process == null || process.IsRunning) { |
||||
runningThreads.Clear(); |
||||
} else { |
||||
process.EnqueueForEach( |
||||
Dispatcher.CurrentDispatcher, |
||||
process.Threads.ToList(), |
||||
t => AddThread(t) |
||||
); |
||||
} |
||||
} |
||||
|
||||
void RunningThreadsListItemActivate(object sender, EventArgs e) |
||||
{ |
||||
ThreadModel obj = runningThreadsList.SelectedItems[0] as ThreadModel; |
||||
|
||||
if (WindowsDebugger.CurrentProcess != null) { |
||||
if (WindowsDebugger.CurrentProcess.IsPaused) { |
||||
WindowsDebugger.CurrentThread = obj.Thread; |
||||
WindowsDebugger.RefreshPads(); |
||||
// TODO: Jump to current line
|
||||
} else { |
||||
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddThread(Thread thread) |
||||
{ |
||||
if (thread == null) return; |
||||
|
||||
// remove the object if exists
|
||||
RemoveThread(thread); |
||||
|
||||
ThreadModel obj = new ThreadModel(thread); |
||||
|
||||
runningThreads.Add(obj); |
||||
} |
||||
|
||||
void RemoveThread(Thread thread) |
||||
{ |
||||
if (thread == null) |
||||
return; |
||||
|
||||
runningThreads.RemoveWhere(model => model.Thread == thread); |
||||
} |
||||
} |
||||
|
||||
static class ListViewExtensions |
||||
{ |
||||
public static void ClearColumns(this ListView view) |
||||
{ |
||||
if (view == null) |
||||
throw new ArgumentNullException("view"); |
||||
if (view.View is GridView) |
||||
((GridView)view.View).Columns.Clear(); |
||||
} |
||||
|
||||
public static void AddColumn(this ListView view, string header, Binding binding, double width) |
||||
{ |
||||
if (view == null) |
||||
throw new ArgumentNullException("view"); |
||||
if (view.View is GridView) { |
||||
GridViewColumn column = new GridViewColumn { |
||||
Width = width, |
||||
DisplayMemberBinding = binding, |
||||
Header = header }; |
||||
((GridView)view.View).Columns.Add(column); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,138 @@
@@ -0,0 +1,138 @@
|
||||
// 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.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
|
||||
using Debugger; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Services; |
||||
using Thread = Debugger.Thread; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class ThreadsPad : AbstractPadContent |
||||
{ |
||||
ListView listView; |
||||
|
||||
public override object Control { |
||||
get { return listView; } |
||||
} |
||||
|
||||
public ThreadsPad() |
||||
{ |
||||
var res = new CommonResources(); |
||||
res.InitializeComponent(); |
||||
|
||||
ContextMenu contextMenu = new ContextMenu(); |
||||
contextMenu.Opened += FillContextMenuStrip; |
||||
|
||||
listView = new ListView(); |
||||
listView.View = (GridView)res["theadsGridView"]; |
||||
listView.ContextMenu = contextMenu; |
||||
listView.MouseDoubleClick += listView_MouseDoubleClick; |
||||
|
||||
WindowsDebugger.RefreshingPads += RefreshPad; |
||||
RefreshPad(); |
||||
} |
||||
|
||||
void RefreshPad() |
||||
{ |
||||
Process process = WindowsDebugger.CurrentProcess; |
||||
|
||||
if (process == null || process.IsRunning) { |
||||
listView.ItemsSource = null; |
||||
} else { |
||||
List<ThreadItem> items = new List<ThreadItem>(); |
||||
foreach(var thread in process.Threads) { |
||||
items.Add(new ThreadItem(thread)); |
||||
} |
||||
listView.ItemsSource = items; |
||||
} |
||||
} |
||||
|
||||
void listView_MouseDoubleClick(object sender, MouseButtonEventArgs e) |
||||
{ |
||||
ThreadItem item = listView.SelectedItem as ThreadItem; |
||||
|
||||
if (WindowsDebugger.CurrentProcess != null) { |
||||
if (WindowsDebugger.CurrentProcess.IsPaused) { |
||||
WindowsDebugger.CurrentThread = item.Thread; |
||||
WindowsDebugger.Instance.JumpToCurrentLine(); |
||||
WindowsDebugger.RefreshPads(); |
||||
} else { |
||||
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void FillContextMenuStrip(object sender, RoutedEventArgs e) |
||||
{ |
||||
var items = listView.SelectedItems.OfType<ThreadItem>(); |
||||
// Suspended property is safe to access at any point
|
||||
bool suspended = items.All(t => t.Thread.Suspended); |
||||
|
||||
ContextMenu menu = sender as ContextMenu; |
||||
menu.Items.Clear(); |
||||
|
||||
MenuItem freezeItem; |
||||
freezeItem = new MenuItem(); |
||||
freezeItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Freeze"); |
||||
freezeItem.IsChecked = suspended; |
||||
freezeItem.Click += delegate { |
||||
if (WindowsDebugger.CurrentProcess == null || WindowsDebugger.CurrentProcess.IsRunning) { |
||||
MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotFreezeWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.Freeze}"); |
||||
return; |
||||
} |
||||
foreach(ThreadItem item in items.OfType<ThreadItem>()) { |
||||
item.Thread.Suspended = !suspended; |
||||
} |
||||
WindowsDebugger.RefreshPads(); |
||||
}; |
||||
|
||||
menu.Items.Add(freezeItem); |
||||
} |
||||
} |
||||
|
||||
public class ThreadItem |
||||
{ |
||||
public Thread Thread { get; private set; } |
||||
public uint ID { get; private set; } |
||||
public string Name { get; private set; } |
||||
public string Priority { get; private set; } |
||||
public string Frozen { get; private set; } |
||||
|
||||
public ThreadItem(Thread thread) |
||||
{ |
||||
// We want to egarly evaluate the properties while the process is paused
|
||||
// rather then wait until the GUI acesses them at some unspecified point
|
||||
this.Thread = thread; |
||||
this.ID = thread.ID; |
||||
this.Name = thread.Name; |
||||
this.Priority = PriorityToString(thread.Priority); |
||||
this.Frozen = ResourceService.GetString(thread.Suspended ? "Global.Yes" : "Global.No"); |
||||
} |
||||
|
||||
static string PriorityToString(System.Threading.ThreadPriority priority) |
||||
{ |
||||
switch (priority) { |
||||
case System.Threading.ThreadPriority.Highest: |
||||
return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Highest"); |
||||
case System.Threading.ThreadPriority.AboveNormal: |
||||
return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.AboveNormal"); |
||||
case System.Threading.ThreadPriority.Normal: |
||||
return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Normal"); |
||||
case System.Threading.ThreadPriority.BelowNormal: |
||||
return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.BelowNormal"); |
||||
case System.Threading.ThreadPriority.Lowest: |
||||
return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Lowest"); |
||||
default: |
||||
return ResourceService.GetString("Global.NA"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue