Browse Source

Introduce 'RichText' class and use it in new output pad API.

pull/59/merge
Daniel Grunwald 13 years ago
parent
commit
efd7e21b10
  1. 3
      src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs
  2. 3
      src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs
  3. 3
      src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs
  4. 3
      src/AddIns/Analysis/UnitTesting/Service/ITestService.cs
  5. 3
      src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs
  6. 6
      src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
  7. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs
  8. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs
  9. 4
      src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs
  10. 4
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs
  11. 5
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs
  12. 9
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs
  13. 15
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs
  14. 24
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs
  15. 5
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs
  16. 2
      src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs
  17. 6
      src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs
  18. 93
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs
  19. 8
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs
  20. 226
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs
  21. 14
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs
  22. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModelWriter.cs
  23. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  24. 21
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs
  25. 3
      src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs
  26. 35
      src/Main/Base/Project/Editor/Search/SearchResultMatch.cs
  27. 4
      src/Main/Base/Project/Editor/Search/SearchResultsPad.cs
  28. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  29. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  30. 9
      src/Main/Base/Project/Project/Build/BuildError.cs
  31. 4
      src/Main/Base/Project/Project/Build/IBuildFeedbackSink.cs
  32. 5
      src/Main/Base/Project/Services/SD.cs
  33. 33
      src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs
  34. 34
      src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/MessageViewCategory.cs
  35. 5
      src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/MessageViewCategoryTextWriter.cs
  36. 5
      src/Main/Base/Project/Util/ProcessRunner.cs
  37. 69
      src/Main/Base/Project/Workbench/IOutputPad.cs
  38. 19
      src/Main/SharpDevelop/Project/Build/BuildEngine.cs
  39. 2
      src/Main/SharpDevelop/Project/Build/BuildService.cs
  40. 9
      src/Main/SharpDevelop/Project/Build/UIBuildFeedbackSink.cs

3
src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/ProfilerProcessRunner.cs

@ -11,6 +11,7 @@ using ICSharpCode.Profiler.Controller;
using ICSharpCode.Profiler.Controller.Data; using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.Profiler.AddIn namespace ICSharpCode.Profiler.AddIn
{ {
@ -39,7 +40,7 @@ namespace ICSharpCode.Profiler.AddIn
wasStarted = false; wasStarted = false;
} }
public Task<int> RunInOutputPadAsync(MessageViewCategory outputCategory, string program, params string[] arguments) public Task<int> RunInOutputPadAsync(IOutputCategory outputCategory, string program, params string[] arguments)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

3
src/AddIns/Analysis/UnitTesting/Interfaces/IUnitTestTaskService.cs

@ -4,12 +4,13 @@
using System; using System;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
{ {
public interface IUnitTestTaskService public interface IUnitTestTaskService
{ {
MessageViewCategory BuildMessageViewCategory { get; } IOutputCategory BuildMessageViewCategory { get; }
void ClearExceptCommentTasks(); void ClearExceptCommentTasks();
void Add(SDTask task); void Add(SDTask task);
bool SomethingWentWrong { get; } bool SomethingWentWrong { get; }

3
src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestTaskService.cs

@ -4,6 +4,7 @@
using System; using System;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
{ {
@ -14,7 +15,7 @@ namespace ICSharpCode.UnitTesting
TaskService.ClearExceptCommentTasks(); TaskService.ClearExceptCommentTasks();
} }
public MessageViewCategory BuildMessageViewCategory { public IOutputCategory BuildMessageViewCategory {
get { return TaskService.BuildMessageViewCategory; } get { return TaskService.BuildMessageViewCategory; }
} }

3
src/AddIns/Analysis/UnitTesting/Service/ITestService.cs

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
{ {
@ -18,7 +19,7 @@ namespace ICSharpCode.UnitTesting
/// </summary> /// </summary>
ITestFramework GetTestFrameworkForProject(IProject project); ITestFramework GetTestFrameworkForProject(IProject project);
MessageViewCategory UnitTestMessageView { get; } IOutputCategory UnitTestMessageView { get; }
/// <summary> /// <summary>
/// Gets the current test solution. /// Gets the current test solution.

3
src/AddIns/Analysis/UnitTesting/Service/SDTestService.cs

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench;
using ICSharpCode.UnitTesting.Frameworks; using ICSharpCode.UnitTesting.Frameworks;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
@ -34,7 +35,7 @@ namespace ICSharpCode.UnitTesting
#region UnitTestMessageView #region UnitTestMessageView
MessageViewCategory unitTestMessageView; MessageViewCategory unitTestMessageView;
public MessageViewCategory UnitTestMessageView { public IOutputCategory UnitTestMessageView {
get { get {
if (unitTestMessageView == null) { if (unitTestMessageView == null) {
MessageViewCategory.Create(ref unitTestMessageView, MessageViewCategory.Create(ref unitTestMessageView,

6
src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs

@ -115,9 +115,9 @@ namespace ICSharpCode.UnitTesting.Frameworks
void ClearTasks() void ClearTasks()
{ {
taskService.BuildMessageViewCategory.ClearText(); taskService.BuildMessageViewCategory.Clear();
taskService.ClearExceptCommentTasks(); taskService.ClearExceptCommentTasks();
testService.UnitTestMessageView.ClearText(); testService.UnitTestMessageView.Clear();
} }
void ShowUnitTestsPad() void ShowUnitTestsPad()
@ -132,7 +132,7 @@ namespace ICSharpCode.UnitTesting.Frameworks
void ShowOutputPad() void ShowOutputPad()
{ {
workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); testService.UnitTestMessageView.Activate(true);
} }
void ResetTestResults() void ResetTestResults()

4
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs

@ -239,8 +239,8 @@ namespace CSharpBinding
{ {
internal readonly string newCode; internal readonly string newCode;
public RenameResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, string newCode, HighlightedInlineBuilder builder = null, HighlightingColor defaultTextColor = null) public RenameResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, string newCode, RichText richText = null, HighlightingColor defaultTextColor = null)
: base(fileName, startLocation, endLocation, offset, length, builder, defaultTextColor) : base(fileName, startLocation, endLocation, offset, length, richText, defaultTextColor)
{ {
this.newCode = newCode; this.newCode = newCode;
} }

4
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CreatePropertiesDialog.xaml.cs

@ -99,9 +99,9 @@ namespace CSharpBinding.Refactoring
AstType interfaceTypeNode = refactoringContext.CreateShortType("System.ComponentModel", "INotifyPropertyChanged", 0); AstType interfaceTypeNode = refactoringContext.CreateShortType("System.ComponentModel", "INotifyPropertyChanged", 0);
var directBaseTypes = currentClass.DirectBaseTypes.Where(t => t.FullName != "System.Object"); var directBaseTypes = currentClass.DirectBaseTypes.Where(t => t.FullName != "System.Object");
if (currentClassDeclaration.BaseTypes.Count > 0) { if (currentClassDeclaration.BaseTypes.Count > 0) {
script.InsertText(insertion, ", " + interfaceTypeNode.GetText() + " "); script.InsertText(insertion, ", " + interfaceTypeNode + " ");
} else { } else {
script.InsertText(insertion, " : " + interfaceTypeNode.GetText() + " "); script.InsertText(insertion, " : " + interfaceTypeNode + " ");
} }
} }

4
src/AddIns/Misc/PackageManagement/Project/Src/ServiceWithWorkbenchOwner.cs

@ -3,7 +3,7 @@
using System; using System;
using System.Windows; using System.Windows;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop;
namespace ICSharpCode.PackageManagement namespace ICSharpCode.PackageManagement
{ {
@ -14,7 +14,7 @@ namespace ICSharpCode.PackageManagement
public Window Owner { public Window Owner {
get { get {
if (owner == null) { if (owner == null) {
owner = WorkbenchSingleton.MainWindow; owner = SD.Workbench.MainWindow;
} }
return owner; return owner;
} }

4
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/FormsCommand.cs

@ -67,7 +67,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run() public override void Run()
{ {
IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow; IWorkbenchWindow window = SD.Workbench.ActiveWorkbenchWindow;
if (window == null) { if (window == null) {
return; return;
} }
@ -89,7 +89,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run() public override void Run()
{ {
PadDescriptor padContent = WorkbenchSingleton.Workbench.GetPad(typeof(ICSharpCode.SharpDevelop.Gui.PropertyPad)); PadDescriptor padContent = SD.Workbench.GetPad(typeof(ICSharpCode.SharpDevelop.Gui.PropertyPad));
if (padContent != null) { if (padContent != null) {
padContent.BringPadToFront(); padContent.BringPadToFront();
} }

5
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Commands/PreviewCommands.cs

@ -4,6 +4,7 @@
using System; using System;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.Reports.Core; using ICSharpCode.Reports.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Reports.Addin.Commands namespace ICSharpCode.Reports.Addin.Commands
@ -66,7 +67,7 @@ namespace ICSharpCode.Reports.Addin.Commands
public override void Run() public override void Run()
{ {
base.Run(); base.Run();
WorkbenchSingleton.StatusBar.SetMessage("Connect..."); SD.StatusBar.SetMessage("Connect...");
base.ReportViewer.RunReport(base.Model,(ReportParameters)null); base.ReportViewer.RunReport(base.Model,(ReportParameters)null);
} }
} }
@ -84,7 +85,7 @@ namespace ICSharpCode.Reports.Addin.Commands
DataSetFromXsdCommand cmd = new DataSetFromXsdCommand(); DataSetFromXsdCommand cmd = new DataSetFromXsdCommand();
cmd.Run(); cmd.Run();
System.Data.DataSet ds = cmd.DataSet; System.Data.DataSet ds = cmd.DataSet;
WorkbenchSingleton.StatusBar.SetMessage("Connect..."); SD.StatusBar.SetMessage("Connect...");
base.ReportViewer.RunReport(base.Model,ds.Tables[0],null); base.ReportViewer.RunReport(base.Model,ds.Tables[0],null);
} }

9
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportExplorer/ReportExplorerPad.cs

@ -8,6 +8,7 @@ using System.Windows.Forms;
using ICSharpCode.Core.WinForms; using ICSharpCode.Core.WinForms;
using ICSharpCode.Reports.Core; using ICSharpCode.Reports.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench; using ICSharpCode.SharpDevelop.Workbench;
@ -29,8 +30,8 @@ namespace ICSharpCode.Reports.Addin
public ReportExplorerPad():base() public ReportExplorerPad():base()
{ {
WorkbenchSingleton.Workbench.ActiveViewContentChanged += ActiveViewContentChanged; SD.Workbench.ActiveViewContentChanged += ActiveViewContentChanged;
WorkbenchSingleton.Workbench.ViewClosed += ActiveViewClosed; SD.Workbench.ViewClosed += ActiveViewClosed;
this.explorerTree = new ExplorerTree(); this.explorerTree = new ExplorerTree();
this.explorerTree.MouseDown += new MouseEventHandler(ReportExplorer_MouseDown); this.explorerTree.MouseDown += new MouseEventHandler(ReportExplorer_MouseDown);
this.explorerTree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ReportExplorerPad_PropertyChanged); this.explorerTree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ReportExplorerPad_PropertyChanged);
@ -63,7 +64,7 @@ namespace ICSharpCode.Reports.Addin
void ActiveViewContentChanged(object source, EventArgs e) void ActiveViewContentChanged(object source, EventArgs e)
{ {
ReportDesignerView vv = WorkbenchSingleton.Workbench.ActiveViewContent as ReportDesignerView; ReportDesignerView vv = SD.Workbench.ActiveViewContent as ReportDesignerView;
if (vv != null) { if (vv != null) {
Console.WriteLine("Explorerpad:ActiveViewContentChanged {0}",vv.TitleName); Console.WriteLine("Explorerpad:ActiveViewContentChanged {0}",vv.TitleName);
} }
@ -184,7 +185,7 @@ namespace ICSharpCode.Reports.Addin
/// </summary> /// </summary>
public override void Dispose() public override void Dispose()
{ {
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= ActiveViewContentChanged; SD.Workbench.ActiveViewContentChanged -= ActiveViewContentChanged;
this.explorerTree.Dispose(); this.explorerTree.Dispose();
} }

15
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/BaseSettingsPanel.cs

@ -224,15 +224,12 @@ namespace ICSharpCode.Reports.Addin.ReportWizard{
private void OnSelectFolder(object sender, System.EventArgs e) private void OnSelectFolder(object sender, System.EventArgs e)
{ {
using (FolderBrowserDialog fd = FileService.CreateFolderBrowserDialog("")) { string selectedPath = SD.FileService.BrowseForFolder("");
if (fd.ShowDialog() == DialogResult.OK) { if (!String.IsNullOrEmpty(selectedPath)) {
if (!String.IsNullOrEmpty(fd.SelectedPath)) { if (!selectedPath.EndsWith(@"\",StringComparison.OrdinalIgnoreCase)){
if (!fd.SelectedPath.EndsWith(@"\",StringComparison.OrdinalIgnoreCase)){ this.txtPath.Text = selectedPath + @"\";
this.txtPath.Text = fd.SelectedPath + @"\"; } else {
} else { this.txtPath.Text = selectedPath;
this.txtPath.Text = fd.SelectedPath;
}
}
} }
} }
} }

24
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/ReportWizard/WizardPanels/Wizard/AbstractOptionPanel.cs

@ -196,20 +196,16 @@ namespace ICSharpCode.Reports.Addin.ReportWizard
startLocation = FileUtility.GetAbsolutePath(startLocation, text); startLocation = FileUtility.GetAbsolutePath(startLocation, text);
} }
using (FolderBrowserDialog fdiag = FileService.CreateFolderBrowserDialog(description, startLocation)) { string path = SD.FileService.BrowseForFolder(description, startLocation);
if (fdiag.ShowDialog() == DialogResult.OK) { if (panel.baseDirectory != null) {
string path = fdiag.SelectedPath; path = FileUtility.GetRelativePath(panel.baseDirectory, path);
if (panel.baseDirectory != null) { }
path = FileUtility.GetRelativePath(panel.baseDirectory, path); if (!path.EndsWith("\\", StringComparison.Ordinal) && !path.EndsWith("/", StringComparison.Ordinal))
} path += "\\";
if (!path.EndsWith("\\") && !path.EndsWith("/")) if (textBoxEditMode == TextBoxEditMode.EditEvaluatedProperty) {
path += "\\"; panel.ControlDictionary[target].Text = path;
if (textBoxEditMode == TextBoxEditMode.EditEvaluatedProperty) { } else {
panel.ControlDictionary[target].Text = path; panel.ControlDictionary[target].Text = MSBuildInternals.Escape(path);
} else {
panel.ControlDictionary[target].Text = MSBuildInternals.Escape(path);
}
}
} }
} }
} }

5
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Services/UIService.cs

@ -8,11 +8,12 @@ using System.Windows.Forms;
using System.Windows.Forms.Design; using System.Windows.Forms.Design;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Reports.Addin namespace ICSharpCode.Reports.Addin
{ {
public class UIService : IUIService public class UIService : System.Windows.Forms.Design.IUIService
{ {
IDictionary styles = new Hashtable(); IDictionary styles = new Hashtable();
@ -48,7 +49,7 @@ namespace ICSharpCode.Reports.Addin
#region Dialog functions #region Dialog functions
public IWin32Window GetDialogOwnerWindow() public IWin32Window GetDialogOwnerWindow()
{ {
return WorkbenchSingleton.MainWin32Window; return SD.WinForms.MainWin32Window;
} }
public DialogResult ShowDialog(Form form) public DialogResult ShowDialog(Form form)

2
src/AddIns/Misc/Reports/ICSharpCode.Reports.Addin/Project/Toolbox/ToolboxProvider.cs

@ -149,7 +149,7 @@ namespace ICSharpCode.Reports.Addin
public static SharpDevelopSideBar ReportingSideBar { public static SharpDevelopSideBar ReportingSideBar {
get { get {
Debug.Assert(WorkbenchSingleton.InvokeRequired == false); SD.MainThread.VerifyAccess();
if (reportingSideBar == null) { if (reportingSideBar == null) {
reportingSideBar = new SharpDevelopSideBar(); reportingSideBar = new SharpDevelopSideBar();
reportingSideBar.Tabs.Add(standardSideTab); reportingSideBar.Tabs.Add(standardSideTab);

6
src/AddIns/Misc/SearchAndReplace/Project/Gui/SearchResultNode.cs

@ -66,11 +66,9 @@ namespace SearchAndReplace
textBlock.Inlines.Add("(" + location.Line + ", " + location.Column + ")\t"); textBlock.Inlines.Add("(" + location.Line + ", " + location.Column + ")\t");
string displayText = result.DisplayText; RichText displayText = result.DisplayText;
if (displayText != null) { if (displayText != null) {
textBlock.Inlines.Add(displayText); HighlightedInlineBuilder builder = new HighlightedInlineBuilder(displayText);
} else if (result.Builder != null) {
HighlightedInlineBuilder builder = result.Builder;
if (IsSelected) { if (IsSelected) {
builder = builder.Clone(); builder = builder.Clone();
builder.SetForeground(0, builder.Text.Length, null); builder.SetForeground(0, builder.Text.Length, null);

93
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedInlineBuilder.cs

@ -9,6 +9,7 @@ using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.AvalonEdit.Highlighting namespace ICSharpCode.AvalonEdit.Highlighting
{ {
@ -23,29 +24,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </remarks> /// </remarks>
public sealed class HighlightedInlineBuilder public sealed class HighlightedInlineBuilder
{ {
sealed class HighlightingState static HighlightingBrush MakeBrush(Brush b)
{ {
internal Brush Foreground; SolidColorBrush scb = b as SolidColorBrush;
internal Brush Background; if (scb != null)
internal FontFamily Family; return new SimpleHighlightingBrush(scb);
internal FontWeight? Weight; else
internal FontStyle? Style; return null;
public HighlightingState Clone()
{
return new HighlightingState {
Foreground = this.Foreground,
Background = this.Background,
Family = this.Family,
Weight = this.Weight,
Style = this.Style
};
}
} }
readonly string text; readonly string text;
List<int> stateChangeOffsets = new List<int>(); List<int> stateChangeOffsets = new List<int>();
List<HighlightingState> stateChanges = new List<HighlightingState>(); List<HighlightingColor> stateChanges = new List<HighlightingColor>();
int GetIndexForOffset(int offset) int GetIndexForOffset(int offset)
{ {
@ -71,10 +61,22 @@ namespace ICSharpCode.AvalonEdit.Highlighting
throw new ArgumentNullException("text"); throw new ArgumentNullException("text");
this.text = text; this.text = text;
stateChangeOffsets.Add(0); stateChangeOffsets.Add(0);
stateChanges.Add(new HighlightingState()); stateChanges.Add(new HighlightingColor());
} }
HighlightedInlineBuilder(string text, List<int> offsets, List<HighlightingState> states) /// <summary>
/// Creates a new HighlightedInlineBuilder instance.
/// </summary>
public HighlightedInlineBuilder(RichText text)
{
if (text == null)
throw new ArgumentNullException("text");
this.text = text.Text;
stateChangeOffsets.AddRange(text.stateChangeOffsets);
stateChanges.AddRange(text.stateChanges);
}
HighlightedInlineBuilder(string text, List<int> offsets, List<HighlightingColor> states)
{ {
this.text = text; this.text = text;
stateChangeOffsets = offsets; stateChangeOffsets = offsets;
@ -104,15 +106,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
HighlightingState state = stateChanges[i]; stateChanges[i].MergeWith(color);
if (color.Foreground != null)
state.Foreground = color.Foreground.GetBrush(null);
if (color.Background != null)
state.Background = color.Background.GetBrush(null);
if (color.FontStyle != null)
state.Style = color.FontStyle;
if (color.FontWeight != null)
state.Weight = color.FontWeight;
} }
} }
@ -123,8 +117,9 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{ {
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
var hbrush = MakeBrush(brush);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
stateChanges[i].Foreground = brush; stateChanges[i].Foreground = hbrush;
} }
} }
@ -135,8 +130,9 @@ namespace ICSharpCode.AvalonEdit.Highlighting
{ {
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
var hbrush = MakeBrush(brush);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
stateChanges[i].Background = brush; stateChanges[i].Background = hbrush;
} }
} }
@ -148,7 +144,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
stateChanges[i].Weight = weight; stateChanges[i].FontWeight = weight;
} }
} }
@ -160,7 +156,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
stateChanges[i].Style = style; stateChanges[i].FontStyle = style;
} }
} }
@ -172,7 +168,8 @@ namespace ICSharpCode.AvalonEdit.Highlighting
int startIndex = GetIndexForOffset(offset); int startIndex = GetIndexForOffset(offset);
int endIndex = GetIndexForOffset(offset + length); int endIndex = GetIndexForOffset(offset + length);
for (int i = startIndex; i < endIndex; i++) { for (int i = startIndex; i < endIndex; i++) {
stateChanges[i].Family = family; throw new NotSupportedException();
//stateChanges[i].FontFamily = family;
} }
} }
@ -181,25 +178,15 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// </summary> /// </summary>
public Run[] CreateRuns() public Run[] CreateRuns()
{ {
Run[] runs = new Run[stateChanges.Count]; return ToRichText().CreateRuns();
for (int i = 0; i < runs.Length; i++) { }
int startOffset = stateChangeOffsets[i];
int endOffset = i + 1 < stateChangeOffsets.Count ? stateChangeOffsets[i + 1] : text.Length; /// <summary>
Run r = new Run(text.Substring(startOffset, endOffset - startOffset)); /// Creates a RichText instance.
HighlightingState state = stateChanges[i]; /// </summary>
if (state.Foreground != null) public RichText ToRichText()
r.Foreground = state.Foreground; {
if (state.Background != null) return new RichText(text, stateChangeOffsets.ToArray(), stateChanges.Select(FreezableHelper.GetFrozenClone).ToArray());
r.Background = state.Background;
if (state.Weight != null)
r.FontWeight = state.Weight.Value;
if (state.Family != null)
r.FontFamily = state.Family;
if (state.Style != null)
r.FontStyle = state.Style.Value;
runs[i] = r;
}
return runs;
} }
/// <summary> /// <summary>

8
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightedLine.cs

@ -296,5 +296,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting
} }
return builder; return builder;
} }
/// <summary>
/// Creates a <see cref="RichText"/> that stores the text and highlighting of this line.
/// </summary>
public RichText ToRichText()
{
return ToInlineBuilder().ToRichText();
}
} }
} }

226
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichText.cs

@ -0,0 +1,226 @@
// 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.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Documents;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Highlighting
{
/// <summary>
/// Represents a immutable piece text with highlighting information.
/// </summary>
public class RichText
{
readonly string text;
internal readonly int[] stateChangeOffsets;
internal readonly HighlightingColor[] stateChanges;
/// <summary>
/// Creates a RichText instance with the given text and RichTextModel.
/// </summary>
/// <param name="text">
/// The text to use in this RichText instance.
/// </param>
/// <param name="model">
/// The model that contains the formatting to use for this RichText instance.
/// <c>model.DocumentLength</c> should correspond to <c>text.Length</c>.
/// This parameter may be null, in which case the RichText instance just holds plain text.
/// </param>
public RichText(string text, RichTextModel model = null)
{
if (text == null)
throw new ArgumentNullException("text");
this.text = text;
if (model != null) {
var sections = model.GetHighlightedSections(0, text.Length).ToArray();
stateChangeOffsets = new int[sections.Length];
stateChanges = new HighlightingColor[sections.Length];
for (int i = 0; i < sections.Length; i++) {
stateChangeOffsets[i] = sections[i].Offset;
stateChanges[i] = sections[i].Color;
}
} else {
stateChangeOffsets = new int[] { 0 };
stateChanges = new HighlightingColor[] { HighlightingColor.Empty };
}
}
internal RichText(string text, int[] offsets, HighlightingColor[] states)
{
this.text = text;
this.stateChangeOffsets = offsets;
this.stateChanges = states;
}
/// <summary>
/// Gets the text.
/// </summary>
public string Text {
get { return text; }
}
/// <summary>
/// Gets the text length.
/// </summary>
public int Length {
get { return text.Length; }
}
int GetIndexForOffset(int offset)
{
if (offset < 0 || offset > text.Length)
throw new ArgumentOutOfRangeException("offset");
int index = Array.BinarySearch(stateChangeOffsets, offset);
if (index < 0) {
// If no color change exists directly at offset,
// return the index of the color segment that contains offset.
index = ~index - 1;
}
return index;
}
int GetEnd(int index)
{
// Gets the end of the color segment no. index.
if (index + 1 < stateChangeOffsets.Length)
return stateChangeOffsets[index + 1];
else
return text.Length;
}
/// <summary>
/// Gets the HighlightingColor for the specified offset.
/// </summary>
public HighlightingColor GetHighlightingAt(int offset)
{
return stateChanges[GetIndexForOffset(offset)];
}
/// <summary>
/// Retrieves the highlighted sections in the specified range.
/// The highlighted sections will be sorted by offset, and there will not be any nested or overlapping sections.
/// </summary>
public IEnumerable<HighlightedSection> GetHighlightedSections(int offset, int length)
{
int index = GetIndexForOffset(offset);
int pos = offset;
int endOffset = offset + length;
while (pos < endOffset) {
int endPos = Math.Min(endOffset, GetEnd(index));
yield return new HighlightedSection {
Offset = pos,
Length = endPos - pos,
Color = stateChanges[index]
};
pos = endPos;
index++;
}
}
/// <summary>
/// Creates a new RichTextModel with the formatting from this RichText.
/// </summary>
public RichTextModel ToRichTextModel()
{
return new RichTextModel(GetHighlightedSections(0, this.Length));
}
/// <summary>
/// Gets the text.
/// </summary>
public override string ToString()
{
return text;
}
/// <summary>
/// Creates WPF Run instances that can be used for TextBlock.Inlines.
/// </summary>
public Run[] CreateRuns()
{
Run[] runs = new Run[stateChanges.Length];
for (int i = 0; i < runs.Length; i++) {
int startOffset = stateChangeOffsets[i];
int endOffset = i + 1 < stateChangeOffsets.Length ? stateChangeOffsets[i + 1] : text.Length;
Run r = new Run(text.Substring(startOffset, endOffset - startOffset));
HighlightingColor state = stateChanges[i];
if (state.Foreground != null)
r.Foreground = state.Foreground.GetBrush(null);
if (state.Background != null)
r.Background = state.Background.GetBrush(null);
if (state.FontWeight != null)
r.FontWeight = state.FontWeight.Value;
if (state.FontStyle != null)
r.FontStyle = state.FontStyle.Value;
runs[i] = r;
}
return runs;
}
/// <summary>
/// Produces HTML code for the line, with &lt;span style="..."&gt; tags.
/// </summary>
public string ToHtml(HtmlOptions options = null)
{
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
htmlWriter.Write(this);
}
return stringWriter.ToString();
}
/// <summary>
/// Produces HTML code for a section of the line, with &lt;span style="..."&gt; tags.
/// </summary>
public string ToHtml(int offset, int length, HtmlOptions options = null)
{
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
using (var htmlWriter = new HtmlRichTextWriter(stringWriter, options)) {
htmlWriter.Write(this, offset, length);
}
return stringWriter.ToString();
}
/// <summary>
/// Creates a substring of this rich text.
/// </summary>
public RichText Substring(int offset, int length)
{
// if (offset == 0 && length == this.Length)
// return this;
throw new NotImplementedException();
}
/// <summary>
/// Concatenates the specified rich texts.
/// </summary>
public static RichText Concat(params RichText[] texts)
{
throw new NotImplementedException();
}
/// <summary>
/// Concatenates the specified rich texts.
/// </summary>
public static RichText operator +(RichText a, RichText b)
{
return RichText.Concat(a, b);
}
/// <summary>
/// Implicit conversion from string to RichText.
/// </summary>
public static implicit operator RichText(string text)
{
if (text != null)
return new RichText(text);
else
return null;
}
}
}

14
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModel.cs

@ -14,7 +14,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <summary> /// <summary>
/// Stores rich-text formatting. /// Stores rich-text formatting.
/// </summary> /// </summary>
public sealed class RichTextModel public sealed class RichTextModel // TODO: maybe rename to HighlightingModel?
{ {
CompressingTreeList<HighlightingColor> list = new CompressingTreeList<HighlightingColor>(object.Equals); CompressingTreeList<HighlightingColor> list = new CompressingTreeList<HighlightingColor>(object.Equals);
@ -34,6 +34,16 @@ namespace ICSharpCode.AvalonEdit.Highlighting
list.InsertRange(0, documentLength, HighlightingColor.Empty); list.InsertRange(0, documentLength, HighlightingColor.Empty);
} }
/// <summary>
/// Creates a RichTextModel from a CONTIGUOUS list of HighlightedSections.
/// </summary>
internal RichTextModel(IEnumerable<HighlightedSection> sections)
{
foreach (var section in sections) {
list.InsertRange(section.Offset, section.Length, section.Color);
}
}
#region UpdateOffsets #region UpdateOffsets
/// <summary> /// <summary>
/// Updates the start and end offsets of all segments stored in this collection. /// Updates the start and end offsets of all segments stored in this collection.
@ -80,7 +90,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <summary> /// <summary>
/// Gets the HighlightingColor for the specified offset. /// Gets the HighlightingColor for the specified offset.
/// </summary> /// </summary>
public HighlightingColor GetHighlighting(int offset) public HighlightingColor GetHighlightingAt(int offset)
{ {
return list[offset]; return list[offset];
} }

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/RichTextModelWriter.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
if (richTextModel.DocumentLength == 0) if (richTextModel.DocumentLength == 0)
currentColor = HighlightingColor.Empty; currentColor = HighlightingColor.Empty;
else else
currentColor = richTextModel.GetHighlighting(Math.Max(0, insertionOffset - 1)); currentColor = richTextModel.GetHighlightingAt(Math.Max(0, insertionOffset - 1));
} }
/// <summary> /// <summary>

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -207,6 +207,7 @@
<Compile Include="Highlighting\HighlightingSpan.cs" /> <Compile Include="Highlighting\HighlightingSpan.cs" />
<Compile Include="Highlighting\IHighlightingDefinitionReferenceResolver.cs"> <Compile Include="Highlighting\IHighlightingDefinitionReferenceResolver.cs">
</Compile> </Compile>
<Compile Include="Highlighting\RichText.cs" />
<Compile Include="Highlighting\RichTextColorizer.cs" /> <Compile Include="Highlighting\RichTextColorizer.cs" />
<Compile Include="Highlighting\RichTextModel.cs" /> <Compile Include="Highlighting\RichTextModel.cs" />
<Compile Include="Highlighting\RichTextModelWriter.cs" /> <Compile Include="Highlighting\RichTextModelWriter.cs" />

21
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/RichTextWriter.cs

@ -5,6 +5,7 @@ using System;
using System.IO; using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.AvalonEdit.Utils namespace ICSharpCode.AvalonEdit.Utils
{ {
@ -19,6 +20,26 @@ namespace ICSharpCode.AvalonEdit.Utils
/// </summary> /// </summary>
protected abstract void BeginUnhandledSpan(); protected abstract void BeginUnhandledSpan();
/// <summary>
/// Writes the RichText instance.
/// </summary>
public void Write(RichText richText)
{
Write(richText, 0, richText.Length);
}
/// <summary>
/// Writes the RichText instance.
/// </summary>
public virtual void Write(RichText richText, int offset, int length)
{
foreach (var section in richText.GetHighlightedSections(offset, length)) {
BeginSpan(section.Color);
Write(richText.Text.Substring(section.Offset, section.Length));
EndSpan();
}
}
/// <summary> /// <summary>
/// Begin a colored span. /// Begin a colored span.
/// </summary> /// </summary>

3
src/Libraries/NRefactory/ICSharpCode.NRefactory/Properties/GlobalAssemblyInfo.cs

@ -40,5 +40,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("5.0.0.0")] [assembly: AssemblyVersion("5.0.0.0")]
// [AssemblyFileVersion] is the version of the NuGet package, // [AssemblyFileVersion] is the version of the NuGet package,
// should follow http://semver.org/ rules // Versions with breaking changes / new features should increment the 'minor' (2nd) number.
// Bugfix releases should increment the 'build' (3rd) number.
[assembly: AssemblyFileVersion("5.3.0")] [assembly: AssemblyFileVersion("5.3.0")]

35
src/Main/Base/Project/Editor/Search/SearchResultMatch.cs

@ -22,7 +22,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
int length; int length;
TextLocation startLocation; TextLocation startLocation;
TextLocation endLocation; TextLocation endLocation;
HighlightedInlineBuilder builder; RichText displayText;
HighlightingColor defaultTextColor; HighlightingColor defaultTextColor;
public FileName FileName { public FileName FileName {
@ -37,10 +37,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
get { return endLocation; } get { return endLocation; }
} }
public HighlightedInlineBuilder Builder {
get { return builder; }
}
public HighlightingColor DefaultTextColor { public HighlightingColor DefaultTextColor {
get { return defaultTextColor; } get { return defaultTextColor; }
} }
@ -62,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
return pattern; return pattern;
} }
public SearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, HighlightedInlineBuilder builder, HighlightingColor defaultTextColor) public SearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, RichText displayText, HighlightingColor defaultTextColor)
{ {
if (fileName == null) if (fileName == null)
throw new ArgumentNullException("fileName"); throw new ArgumentNullException("fileName");
@ -71,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
this.endLocation = endLocation; this.endLocation = endLocation;
this.offset = offset; this.offset = offset;
this.length = length; this.length = length;
this.builder = builder; this.displayText = displayText;
this.defaultTextColor = defaultTextColor; this.defaultTextColor = defaultTextColor;
} }
@ -90,9 +86,9 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
/// <summary> /// <summary>
/// Gets a special text to display, or null to display the line's content. /// Gets a special text to display, or null to display the line's content.
/// </summary> /// </summary>
public virtual string DisplayText { public RichText DisplayText {
get { get {
return null; return displayText;
} }
} }
@ -104,29 +100,12 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
} }
} }
public class SimpleSearchResultMatch : SearchResultMatch
{
string displayText;
public override string DisplayText {
get {
return displayText;
}
}
public SimpleSearchResultMatch(FileName fileName, TextLocation position, int offset, string displayText)
: base(fileName, position, position, offset, 0, null, null)
{
this.displayText = displayText;
}
}
public class AvalonEditSearchResultMatch : SearchResultMatch public class AvalonEditSearchResultMatch : SearchResultMatch
{ {
ICSharpCode.AvalonEdit.Search.ISearchResult match; ICSharpCode.AvalonEdit.Search.ISearchResult match;
public AvalonEditSearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, HighlightedInlineBuilder builder, HighlightingColor defaultTextColor, ICSharpCode.AvalonEdit.Search.ISearchResult match) public AvalonEditSearchResultMatch(FileName fileName, TextLocation startLocation, TextLocation endLocation, int offset, int length, RichText richText, HighlightingColor defaultTextColor, ICSharpCode.AvalonEdit.Search.ISearchResult match)
: base(fileName, startLocation, endLocation, offset, length, builder, defaultTextColor) : base(fileName, startLocation, endLocation, offset, length, richText, defaultTextColor)
{ {
this.match = match; this.match = match;
} }

4
src/Main/Base/Project/Editor/Search/SearchResultsPad.cs

@ -149,7 +149,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
return new DummySearchResult { Text = title }; return new DummySearchResult { Text = title };
} }
public static HighlightedInlineBuilder CreateInlineBuilder(TextLocation startPosition, TextLocation endPosition, IDocument document, IHighlighter highlighter) public static RichText CreateInlineBuilder(TextLocation startPosition, TextLocation endPosition, IDocument document, IHighlighter highlighter)
{ {
if (startPosition.Line >= 1 && startPosition.Line <= document.LineCount) { if (startPosition.Line >= 1 && startPosition.Line <= document.LineCount) {
var inlineBuilder = highlighter.HighlightLine(startPosition.Line).ToInlineBuilder(); var inlineBuilder = highlighter.HighlightLine(startPosition.Line).ToInlineBuilder();
@ -166,7 +166,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Search
inlineBuilder.SetFontWeight(startOffset, endOffset - startOffset, FontWeights.Bold); inlineBuilder.SetFontWeight(startOffset, endOffset - startOffset, FontWeights.Bold);
} }
} }
return inlineBuilder; return inlineBuilder.ToRichText();
} }
return null; return null;
} }

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -165,11 +165,12 @@
class = "ICSharpCode.SharpDevelop.Gui.TaskListPad" class = "ICSharpCode.SharpDevelop.Gui.TaskListPad"
defaultPosition = "Bottom" /> defaultPosition = "Bottom" />
<Pad id = "CompilerMessageView" <Pad id = "OutputPad"
category = "Main" category = "Main"
title = "${res:MainWindow.Windows.OutputWindow}" title = "${res:MainWindow.Windows.OutputWindow}"
icon = "PadIcons.Output" icon = "PadIcons.Output"
class = "ICSharpCode.SharpDevelop.Gui.CompilerMessageView" class = "ICSharpCode.SharpDevelop.Gui.CompilerMessageView"
serviceInterface = "ICSharpCode.SharpDevelop.Workbench.IOutputPad"
defaultPosition = "Bottom" /> defaultPosition = "Bottom" />
<Pad id = "PropertyPad" <Pad id = "PropertyPad"

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -330,6 +330,7 @@
<Compile Include="Workbench\File\FileService.cs" /> <Compile Include="Workbench\File\FileService.cs" />
<Compile Include="Workbench\File\IRecentOpen.cs" /> <Compile Include="Workbench\File\IRecentOpen.cs" />
<Compile Include="Workbench\ICustomizedCommands.cs" /> <Compile Include="Workbench\ICustomizedCommands.cs" />
<Compile Include="Workbench\IOutputPad.cs" />
<Compile Include="Workbench\IPadContent.cs" /> <Compile Include="Workbench\IPadContent.cs" />
<Compile Include="Workbench\IShutdownService.cs" /> <Compile Include="Workbench\IShutdownService.cs" />
<Compile Include="Workbench\IViewContent.cs" /> <Compile Include="Workbench\IViewContent.cs" />

9
src/Main/Base/Project/Project/Build/BuildError.cs

@ -3,6 +3,9 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Core; using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
@ -164,5 +167,11 @@ namespace ICSharpCode.SharpDevelop.Project
this.ErrorCode, this.ErrorText); this.ErrorCode, this.ErrorText);
} }
} }
public RichText ToRichText()
{
// TODO: add some color
return new RichText(ToString());
}
} }
} }

4
src/Main/Base/Project/Project/Build/IBuildFeedbackSink.cs

@ -2,6 +2,8 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {
@ -25,6 +27,6 @@ namespace ICSharpCode.SharpDevelop.Project
/// Reports a build message. /// Reports a build message.
/// This member is thread-safe. /// This member is thread-safe.
/// </summary> /// </summary>
void ReportMessage(string message); void ReportMessage(RichText message);
} }
} }

5
src/Main/Base/Project/Services/SD.cs

@ -254,5 +254,10 @@ namespace ICSharpCode.SharpDevelop
public static IFileSystem FileSystem { public static IFileSystem FileSystem {
get { return GetRequiredService<IFileSystem>(); } get { return GetRequiredService<IFileSystem>(); }
} }
/// <inheritdoc see="IOutputPad"/>
public static IOutputPad OutputPad {
get { return GetRequiredService<IOutputPad>(); }
}
} }
} }

33
src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/CompilerMessageView.cs

@ -29,8 +29,39 @@ namespace ICSharpCode.SharpDevelop.Gui
/// This class displays the errors and warnings which the compiler outputs and /// This class displays the errors and warnings which the compiler outputs and
/// allows the user to jump to the source of the warning / error /// allows the user to jump to the source of the warning / error
/// </summary> /// </summary>
public class CompilerMessageView : AbstractPadContent, IClipboardHandler public class CompilerMessageView : AbstractPadContent, IClipboardHandler, IOutputPad
{ {
#region IOutputPad implementation
IOutputCategory IOutputPad.CreateCategory(string displayName)
{
var cat = new MessageViewCategory(displayName, displayName);
AddCategory(cat);
return cat;
}
void IOutputPad.RemoveCategory(IOutputCategory category)
{
throw new NotImplementedException();
}
IOutputCategory IOutputPad.CurrentCategory {
get {
return this.SelectedMessageViewCategory;
}
set {
throw new NotImplementedException();
}
}
IOutputCategory IOutputPad.BuildCategory {
get {
return TaskService.BuildMessageViewCategory;
}
}
#endregion
static CompilerMessageView instance; static CompilerMessageView instance;
/// <summary> /// <summary>

34
src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/MessageViewCategory.cs

@ -3,6 +3,8 @@
using System; using System;
using System.Text; using System.Text;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Gui namespace ICSharpCode.SharpDevelop.Gui
{ {
@ -10,8 +12,38 @@ namespace ICSharpCode.SharpDevelop.Gui
/// This class represents a category with its text content used in the /// This class represents a category with its text content used in the
/// output pad (CompilerMessageView). /// output pad (CompilerMessageView).
/// </summary> /// </summary>
public class MessageViewCategory public class MessageViewCategory : IOutputCategory
{ {
#region IOutputCategory implementation
void IOutputCategory.Activate(bool bringPadToFront)
{
SD.OutputPad.CurrentCategory = this;
if (bringPadToFront)
SD.OutputPad.BringToFront();
}
void IOutputCategory.Clear()
{
ClearText();
}
void IOutputCategory.AppendText(RichText text)
{
AppendText(text.ToString());
}
void IOutputCategory.AppendLine(RichText text)
{
AppendLine(text.ToString());
}
string IOutputCategory.DisplayName {
get { return displayCategory; }
}
#endregion
#region Static methods to create MessageViewCategories #region Static methods to create MessageViewCategories
/// <summary> /// <summary>
/// Creates a new MessageViewCategory with the specified category /// Creates a new MessageViewCategory with the specified category

5
src/Main/Base/Project/Src/Gui/Pads/CompilerMessageView/MessageViewCategoryTextWriter.cs

@ -4,6 +4,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Gui namespace ICSharpCode.SharpDevelop.Gui
{ {
@ -12,9 +13,9 @@ namespace ICSharpCode.SharpDevelop.Gui
/// </summary> /// </summary>
public class MessageViewCategoryTextWriter : TextWriter public class MessageViewCategoryTextWriter : TextWriter
{ {
readonly MessageViewCategory target; readonly IOutputCategory target;
public MessageViewCategoryTextWriter(MessageViewCategory target) public MessageViewCategoryTextWriter(IOutputCategory target)
{ {
this.target = target; this.target = target;
} }

5
src/Main/Base/Project/Util/ProcessRunner.cs

@ -19,6 +19,7 @@ using ICSharpCode.Core;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Util; using ICSharpCode.SharpDevelop.Util;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop namespace ICSharpCode.SharpDevelop
{ {
@ -38,7 +39,7 @@ namespace ICSharpCode.SharpDevelop
public interface IProcessRunner : IDisposable public interface IProcessRunner : IDisposable
{ {
Task<int> RunInOutputPadAsync(MessageViewCategory outputCategory, string program, params string[] arguments); Task<int> RunInOutputPadAsync(IOutputCategory outputCategory, string program, params string[] arguments);
string WorkingDirectory { get; set; } string WorkingDirectory { get; set; }
ProcessCreationFlags CreationFlags { get; set; } ProcessCreationFlags CreationFlags { get; set; }
IDictionary<string, string> EnvironmentVariables { get; } IDictionary<string, string> EnvironmentVariables { get; }
@ -245,7 +246,7 @@ namespace ICSharpCode.SharpDevelop
#endregion #endregion
#region RunInOutputPad #region RunInOutputPad
public async Task<int> RunInOutputPadAsync(MessageViewCategory outputCategory, string program, params string[] arguments) public async Task<int> RunInOutputPadAsync(IOutputCategory outputCategory, string program, params string[] arguments)
{ {
RedirectStandardOutputAndErrorToSingleStream = true; RedirectStandardOutputAndErrorToSingleStream = true;
Start(program, arguments); Start(program, arguments);

69
src/Main/Base/Project/Workbench/IOutputPad.cs

@ -0,0 +1,69 @@
// 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 ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.SharpDevelop.Workbench
{
/// <summary>
/// The 'Output' pad.
/// Allows showing a text log to the user.
/// </summary>
public interface IOutputPad
{
/// <summary>
/// Opens the pad.
/// </summary>
void BringToFront();
/// <summary>
/// Creates a new output category.
/// </summary>
IOutputCategory CreateCategory(string displayName);
/// <summary>
/// Removes an existing output category.
/// </summary>
void RemoveCategory(IOutputCategory category);
/// <summary>
/// Gets/Sets the current category.
/// This property is thread-safe.
/// </summary>
IOutputCategory CurrentCategory { get; set; }
/// <summary>
/// The "Build" category.
/// </summary>
IOutputCategory BuildCategory { get; }
}
public interface IOutputCategory
{
/// <summary>
/// Gets the display name of this category.
/// </summary>
string DisplayName { get; }
/// <summary>
/// Activates this output category in the UI.
/// </summary>
void Activate(bool bringPadToFront = false);
/// <summary>
/// Clears all text in the category.
/// </summary>
void Clear();
/// <summary>
/// Appends text to this category.
/// </summary>
void AppendText(RichText text);
/// <summary>
/// Appends text to this category, followed by a newline.
/// </summary>
void AppendLine(RichText text);
}
}

19
src/Main/SharpDevelop/Project/Build/BuildEngine.cs

@ -9,6 +9,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
@ -56,7 +57,7 @@ namespace ICSharpCode.SharpDevelop.Project
engine.results.Add(error); engine.results.Add(error);
if (engine.combinedBuildFeedbackSink != null) { if (engine.combinedBuildFeedbackSink != null) {
engine.combinedBuildFeedbackSink.ReportError(error); engine.combinedBuildFeedbackSink.ReportError(error);
engine.combinedBuildFeedbackSink.ReportMessage(error.ToString()); engine.combinedBuildFeedbackSink.ReportMessage(error.ToRichText());
} }
engine.results.Result = BuildResultCode.BuildFileError; engine.results.Result = BuildResultCode.BuildFileError;
@ -133,7 +134,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// <summary>The list of messages that were not reported because another node held the /// <summary>The list of messages that were not reported because another node held the
/// output lock</summary> /// output lock</summary>
internal List<string> unreportedMessageList; internal List<RichText> unreportedMessageList;
public BuildNode(BuildEngine engine, IBuildable project) public BuildNode(BuildEngine engine, IBuildable project)
{ {
@ -166,7 +167,7 @@ namespace ICSharpCode.SharpDevelop.Project
engine.ReportError(this, error); engine.ReportError(this, error);
} }
public void ReportMessage(string message) public void ReportMessage(RichText message)
{ {
engine.ReportMessage(this, message); engine.ReportMessage(this, message);
} }
@ -441,13 +442,13 @@ namespace ICSharpCode.SharpDevelop.Project
if (!error.IsWarning) if (!error.IsWarning)
source.hasErrors = true; source.hasErrors = true;
results.Add(error); results.Add(error);
ReportMessage(source, error.ToString()); ReportMessage(source, error.ToRichText());
if (combinedBuildFeedbackSink != null) { if (combinedBuildFeedbackSink != null) {
combinedBuildFeedbackSink.ReportError(error); combinedBuildFeedbackSink.ReportError(error);
} }
} }
void ReportMessage(BuildNode source, string message) void ReportMessage(BuildNode source, RichText message)
{ {
bool hasOutputLock; bool hasOutputLock;
lock (this) { lock (this) {
@ -458,7 +459,7 @@ namespace ICSharpCode.SharpDevelop.Project
if (!hasOutputLock) { if (!hasOutputLock) {
if (source.unreportedMessageList == null) { if (source.unreportedMessageList == null) {
nodesWaitingForOutputLock.Enqueue(source); nodesWaitingForOutputLock.Enqueue(source);
source.unreportedMessageList = new List<string>(); source.unreportedMessageList = new List<RichText>();
} }
source.unreportedMessageList.Add(message); source.unreportedMessageList.Add(message);
} }
@ -470,7 +471,7 @@ namespace ICSharpCode.SharpDevelop.Project
void LogBuildFinished(BuildNode node) void LogBuildFinished(BuildNode node)
{ {
List<string> messagesToReport = null; List<RichText> messagesToReport = null;
bool newNodeWithOutputLockAlreadyFinishedBuilding = false; bool newNodeWithOutputLockAlreadyFinishedBuilding = false;
lock (this) { lock (this) {
if (node == nodeWithOutputLock) { if (node == nodeWithOutputLock) {
@ -499,10 +500,10 @@ namespace ICSharpCode.SharpDevelop.Project
void ReportMessageLine(string message) void ReportMessageLine(string message)
{ {
ReportMessageInternal(StringParser.Parse(message)); ReportMessageInternal(new RichText(StringParser.Parse(message)));
} }
void ReportMessageInternal(string message) void ReportMessageInternal(RichText message)
{ {
if (combinedBuildFeedbackSink != null) if (combinedBuildFeedbackSink != null)
combinedBuildFeedbackSink.ReportMessage(message); combinedBuildFeedbackSink.ReportMessage(message);

2
src/Main/SharpDevelop/Project/Build/BuildService.cs

@ -68,7 +68,7 @@ namespace ICSharpCode.SharpDevelop.Project
buildable = buildModifiedProjectsOnly.WrapBuildable(buildable, options.BuildDetection); buildable = buildModifiedProjectsOnly.WrapBuildable(buildable, options.BuildDetection);
var sink = new UIBuildFeedbackSink(TaskService.BuildMessageViewCategory, SD.StatusBar); var sink = new UIBuildFeedbackSink(SD.OutputPad.BuildCategory, SD.StatusBar);
// Actually run the build: // Actually run the build:
var results = await BuildEngine.BuildAsync(buildable, options, sink, progressMonitor); var results = await BuildEngine.BuildAsync(buildable, options, sink, progressMonitor);

9
src/Main/SharpDevelop/Project/Build/UIBuildFeedbackSink.cs

@ -8,8 +8,11 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {
@ -18,10 +21,10 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary> /// </summary>
sealed class UIBuildFeedbackSink : IBuildFeedbackSink sealed class UIBuildFeedbackSink : IBuildFeedbackSink
{ {
MessageViewCategory messageView; IOutputCategory messageView;
IStatusBarService statusBarService; IStatusBarService statusBarService;
public UIBuildFeedbackSink(MessageViewCategory messageView, IStatusBarService statusBarService) public UIBuildFeedbackSink(IOutputCategory messageView, IStatusBarService statusBarService)
{ {
Debug.Assert(messageView != null); Debug.Assert(messageView != null);
Debug.Assert(statusBarService != null); Debug.Assert(statusBarService != null);
@ -37,7 +40,7 @@ namespace ICSharpCode.SharpDevelop.Project
}); });
} }
public void ReportMessage(string message) public void ReportMessage(RichText message)
{ {
messageView.AppendLine(message); messageView.AppendLine(message);
} }

Loading…
Cancel
Save