diff --git a/samples/CSharpCodeCompletion/CSharpCodeCompletion.csproj b/samples/CSharpCodeCompletion/CSharpCodeCompletion.csproj index 351c176a15..0f3a9ea2e8 100644 --- a/samples/CSharpCodeCompletion/CSharpCodeCompletion.csproj +++ b/samples/CSharpCodeCompletion/CSharpCodeCompletion.csproj @@ -1,4 +1,4 @@ - + WinExe CSharpEditor @@ -6,12 +6,17 @@ Debug AnyCPU {489CFE09-FDF7-4C89-BAB5-BD09CADD61AD} + v3.5 + False + False + 4 + false bin\Debug\ False DEBUG;TRACE - True + true Full True @@ -23,8 +28,18 @@ None False + + False + Auto + 4194304 + AnyCPU + 4096 + + + 3.5 + @@ -51,6 +66,7 @@ + MainForm.cs @@ -62,6 +78,7 @@ + \ No newline at end of file diff --git a/samples/CSharpCodeCompletion/CSharpCodeCompletion.sln b/samples/CSharpCodeCompletion/CSharpCodeCompletion.sln index 2581545163..d8b4f29568 100644 --- a/samples/CSharpCodeCompletion/CSharpCodeCompletion.sln +++ b/samples/CSharpCodeCompletion/CSharpCodeCompletion.sln @@ -1,6 +1,7 @@  -Microsoft Visual Studio Solution File, Format Version 9.00 -# SharpDevelop 2.1.0.1947 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +# SharpDevelop 3.0.0.2677 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpCodeCompletion", "CSharpCodeCompletion.csproj", "{489CFE09-FDF7-4C89-BAB5-BD09CADD61AD}" EndProject Global diff --git a/samples/CSharpCodeCompletion/CodeCompletionData.cs b/samples/CSharpCodeCompletion/CodeCompletionData.cs new file mode 100644 index 0000000000..8b954e9613 --- /dev/null +++ b/samples/CSharpCodeCompletion/CodeCompletionData.cs @@ -0,0 +1,163 @@ +/* + * Erstellt mit SharpDevelop. + * Benutzer: grunwald + * Datum: 27.08.2007 + * Zeit: 14:25 + * + * Sie können diese Vorlage unter Extras > Optionen > Codeerstellung > Standardheader ändern. + */ + +using System; +using System.IO; +using System.Text; +using System.Xml; + +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.CSharp; +using ICSharpCode.TextEditor.Gui.CompletionWindow; + +namespace CSharpEditor +{ + /// + /// Represents an item in the code completion window. + /// + class CodeCompletionData : DefaultCompletionData, ICompletionData + { + IMember member; + IClass c; + + public CodeCompletionData(IMember member) + : base(member.Name, null, GetMemberImageIndex(member)) + { + this.member = member; + } + + public CodeCompletionData(IClass c) + : base(c.Name, null, GetClassImageIndex(c)) + { + this.c = c; + } + + int overloads = 0; + + public void AddOverload() + { + overloads++; + } + + static int GetMemberImageIndex(IMember member) + { + // Missing: different icons for private/public member + if (member is IMethod) + return 1; + if (member is IProperty) + return 2; + if (member is IField) + return 3; + if (member is IEvent) + return 6; + return 3; + } + + static int GetClassImageIndex(IClass c) + { + switch (c.ClassType) { + case ClassType.Enum: + return 4; + default: + return 0; + } + } + + string description; + + // DefaultCompletionData.Description is not virtual, but we can reimplement + // the interface to get the same effect as overriding. + string ICompletionData.Description { + get { + if (description == null) { + IDecoration entity = (IDecoration)member ?? c; + description = GetCSharpText(entity); + if (overloads > 1) { + description += " (+" + overloads + " overloads)"; + } + description += Environment.NewLine + XmlDocumentationToText(entity.Documentation); + } + return description; + } + } + + /// + /// Converts a member to text. + /// Returns the declaration of the member as C# code, e.g. + /// "public void MemberName(string parameter)" + /// + static string GetCSharpText(IDecoration entity) + { + if (entity is IMethod) + return CSharpAmbience.Instance.Convert(entity as IMethod); + if (entity is IProperty) + return CSharpAmbience.Instance.Convert(entity as IProperty); + if (entity is IEvent) + return CSharpAmbience.Instance.Convert(entity as IEvent); + if (entity is IField) + return CSharpAmbience.Instance.Convert(entity as IField); + if (entity is IClass) + return CSharpAmbience.Instance.Convert(entity as IClass); + // unknown entity: + return entity.ToString(); + } + + public static string XmlDocumentationToText(string xmlDoc) + { + System.Diagnostics.Debug.WriteLine(xmlDoc); + StringBuilder b = new StringBuilder(); + try { + using (XmlTextReader reader = new XmlTextReader(new StringReader("" + xmlDoc + ""))) { + reader.XmlResolver = null; + while (reader.Read()) { + switch (reader.NodeType) { + case XmlNodeType.Text: + b.Append(reader.Value); + break; + case XmlNodeType.Element: + switch (reader.Name) { + case "filterpriority": + reader.Skip(); + break; + case "returns": + b.AppendLine(); + b.Append("Returns: "); + break; + case "param": + b.AppendLine(); + b.Append(reader.GetAttribute("name") + ": "); + break; + case "remarks": + b.AppendLine(); + b.Append("Remarks: "); + break; + case "see": + if (reader.IsEmptyElement) { + b.Append(reader.GetAttribute("cref")); + } else { + reader.MoveToContent(); + if (reader.HasValue) { + b.Append(reader.Value); + } else { + b.Append(reader.GetAttribute("cref")); + } + } + break; + } + break; + } + } + } + return b.ToString(); + } catch (XmlException) { + return xmlDoc; + } + } + } +} diff --git a/samples/CSharpCodeCompletion/CodeCompletionProvider.cs b/samples/CSharpCodeCompletion/CodeCompletionProvider.cs index 72a29e6865..8982a7ee8e 100644 --- a/samples/CSharpCodeCompletion/CodeCompletionProvider.cs +++ b/samples/CSharpCodeCompletion/CodeCompletionProvider.cs @@ -94,8 +94,8 @@ namespace CSharpEditor NRefactoryResolver resolver = new NRefactoryResolver(mainForm.myProjectContent.Language); Dom.ResolveResult rr = resolver.Resolve(FindExpression(textArea), - textArea.Caret.Line, - textArea.Caret.Column, + textArea.Caret.Line + 1, + textArea.Caret.Column + 1, mainForm.parseInformation, textArea.MotherTextEditorControl.Text); List resultList = new List(); @@ -121,11 +121,14 @@ namespace CSharpEditor } else { finder = new Dom.CSharp.CSharpExpressionFinder(mainForm.parseInformation); } - return finder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset - 1); + return finder.FindExpression(textArea.Document.TextContent, textArea.Caret.Offset); } void AddCompletionData(List resultList, ArrayList completionData) { + // used to store method the names for grouping overloads + Dictionary nameDictionary = new Dictionary(); + // Add the completion data as returned by SharpDevelop.Dom to the // list for the text editor foreach (object obj in completionData) { @@ -134,71 +137,28 @@ namespace CSharpEditor resultList.Add(new DefaultCompletionData((string)obj, "namespace " + obj, 5)); } else if (obj is Dom.IClass) { Dom.IClass c = (Dom.IClass)obj; - if (c.ClassType == Dom.ClassType.Enum) { - resultList.Add(new DefaultCompletionData(c.Name, - GetDescription(c), - 4)); - } else { // missing: struct, delegate etc. - resultList.Add(new DefaultCompletionData(c.Name, - GetDescription(c), - 0)); - } + resultList.Add(new CodeCompletionData(c)); } else if (obj is Dom.IMember) { Dom.IMember m = (Dom.IMember)obj; if (m is Dom.IMethod && ((m as Dom.IMethod).IsConstructor)) { // Skip constructors continue; } - // TODO: Group results by name and add "(x Overloads)" to the + // Group results by name and add "(x Overloads)" to the // description if there are multiple results with the same name. - resultList.Add(new DefaultCompletionData(m.Name, - GetDescription(m), - GetMemberImageIndex(m))); + + CodeCompletionData data; + if (nameDictionary.TryGetValue(m.Name, out data)) { + data.AddOverload(); + } else { + nameDictionary[m.Name] = data = new CodeCompletionData(m); + resultList.Add(data); + } } else { // Current ICSharpCode.SharpDevelop.Dom should never return anything else throw new NotSupportedException(); } } } - - /// - /// Converts a member to text. - /// Returns the declaration of the member as C# code, e.g. - /// "public void MemberName(string parameter)" - /// - string GetDescription(Dom.IDecoration entity) - { - return GetCSharpText(entity) + Environment.NewLine + entity.Documentation; - } - - string GetCSharpText(Dom.IDecoration entity) - { - if (entity is Dom.IMethod) - return Dom.CSharp.CSharpAmbience.Instance.Convert(entity as Dom.IMethod); - if (entity is Dom.IProperty) - return Dom.CSharp.CSharpAmbience.Instance.Convert(entity as Dom.IProperty); - if (entity is Dom.IEvent) - return Dom.CSharp.CSharpAmbience.Instance.Convert(entity as Dom.IEvent); - if (entity is Dom.IField) - return Dom.CSharp.CSharpAmbience.Instance.Convert(entity as Dom.IField); - if (entity is Dom.IClass) - return Dom.CSharp.CSharpAmbience.Instance.Convert(entity as Dom.IClass); - // unknown entity: - return entity.ToString(); - } - - int GetMemberImageIndex(Dom.IMember member) - { - // Missing: different icons for private/public member - if (member is Dom.IMethod) - return 1; - if (member is Dom.IProperty) - return 2; - if (member is Dom.IField) - return 3; - if (member is Dom.IEvent) - return 6; - return 3; - } } } diff --git a/samples/CSharpCodeCompletion/MainForm.cs b/samples/CSharpCodeCompletion/MainForm.cs index 9a968fb04d..22c1521f36 100644 --- a/samples/CSharpCodeCompletion/MainForm.cs +++ b/samples/CSharpCodeCompletion/MainForm.cs @@ -97,8 +97,10 @@ class A textEditorControl1.SetHighlighting("C#"); } textEditorControl1.ShowEOLMarkers = false; - CodeCompletionKeyHandler.Attach(this, textEditorControl1); + textEditorControl1.ShowInvalidLines = false; HostCallbackImplementation.Register(this); + CodeCompletionKeyHandler.Attach(this, textEditorControl1); + ToolTipProvider.Attach(this, textEditorControl1); pcRegistry = new Dom.ProjectContentRegistry(); // Default .NET 2.0 registry @@ -135,11 +137,13 @@ class A "System", "System.Data", "System.Drawing", "System.Xml", "System.Windows.Forms", "Microsoft.VisualBasic" }; foreach (string assemblyName in referencedAssemblies) { - { // block for anonymous method (capture assemblyNameCopy correctly) - string assemblyNameCopy = assemblyName; - BeginInvoke(new MethodInvoker(delegate { parserThreadLabel.Text = "Loading " + assemblyNameCopy + "..."; })); + string assemblyNameCopy = assemblyName; // copy for anonymous method + BeginInvoke(new MethodInvoker(delegate { parserThreadLabel.Text = "Loading " + assemblyNameCopy + "..."; })); + Dom.IProjectContent referenceProjectContent = pcRegistry.GetProjectContentForReference(assemblyName, assemblyName); + myProjectContent.AddReferencedContent(referenceProjectContent); + if (referenceProjectContent is Dom.ReflectionProjectContent) { + (referenceProjectContent as Dom.ReflectionProjectContent).InitializeReferences(); } - myProjectContent.AddReferencedContent(pcRegistry.GetProjectContentForReference(assemblyName, assemblyName)); } if (IsVisualBasic) { myProjectContent.DefaultImports = new Dom.DefaultUsing(myProjectContent); diff --git a/samples/CSharpCodeCompletion/ToolTipProvider.cs b/samples/CSharpCodeCompletion/ToolTipProvider.cs new file mode 100644 index 0000000000..4ffed3b7cc --- /dev/null +++ b/samples/CSharpCodeCompletion/ToolTipProvider.cs @@ -0,0 +1,143 @@ +// CSharp Editor Example with Code Completion +// Copyright (c) 2007, Daniel Grunwald +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this list +// of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// - Neither the name of the ICSharpCode team nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using System; +using System.Text; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.CSharp; +using TextEditor = ICSharpCode.TextEditor; +using NRefactoryResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver; + +namespace CSharpEditor +{ + sealed class ToolTipProvider + { + MainForm mainForm; + TextEditor.TextEditorControl editor; + + private ToolTipProvider(MainForm mainForm, TextEditor.TextEditorControl editor) + { + this.mainForm = mainForm; + this.editor = editor; + } + + public static void Attach(MainForm mainForm, TextEditor.TextEditorControl editor) + { + ToolTipProvider tp = new ToolTipProvider(mainForm, editor); + editor.ActiveTextAreaControl.TextArea.ToolTipRequest += tp.OnToolTipRequest; + } + + void OnToolTipRequest(object sender, TextEditor.ToolTipRequestEventArgs e) + { + if (e.InDocument && !e.ToolTipShown) { + CSharpExpressionFinder expressionFinder = new CSharpExpressionFinder(mainForm.parseInformation); + ExpressionResult expression = expressionFinder.FindFullExpression( + editor.Text, + editor.Document.PositionToOffset(e.LogicalPosition)); + + TextEditor.TextArea textArea = editor.ActiveTextAreaControl.TextArea; + NRefactoryResolver resolver = new NRefactoryResolver(mainForm.myProjectContent.Language); + ResolveResult rr = resolver.Resolve(expression, + e.LogicalPosition.Y + 1, + e.LogicalPosition.X + 1, + mainForm.parseInformation, + textArea.MotherTextEditorControl.Text); + string toolTipText = GetText(rr); + if (toolTipText != null) { + e.ShowToolTip(toolTipText); + } + } + } + + static string GetText(ResolveResult result) + { + if (result == null) { + return null; + } + if (result is MixedResolveResult) + return GetText(((MixedResolveResult)result).PrimaryResult); + IAmbience ambience = new CSharpAmbience(); + ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowAccessibility; + if (result is MemberResolveResult) { + return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember); + } else if (result is LocalResolveResult) { + LocalResolveResult rr = (LocalResolveResult)result; + ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames + | ConversionFlags.ShowReturnType; + StringBuilder b = new StringBuilder(); + if (rr.IsParameter) + b.Append("parameter "); + else + b.Append("local variable "); + b.Append(ambience.Convert(rr.Field)); + return b.ToString(); + } else if (result is NamespaceResolveResult) { + return "namespace " + ((NamespaceResolveResult)result).Name; + } else if (result is TypeResolveResult) { + IClass c = ((TypeResolveResult)result).ResolvedClass; + if (c != null) + return GetMemberText(ambience, c); + else + return ambience.Convert(result.ResolvedType); + } else if (result is MethodResolveResult) { + MethodResolveResult mrr = result as MethodResolveResult; + IMethod m = mrr.GetMethodIfSingleOverload(); + if (m != null) + return GetMemberText(ambience, m); + else + return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name; + } else { + return null; + } + } + + static string GetMemberText(IAmbience ambience, IDecoration member) + { + StringBuilder text = new StringBuilder(); + if (member is IField) { + text.Append(ambience.Convert(member as IField)); + } else if (member is IProperty) { + text.Append(ambience.Convert(member as IProperty)); + } else if (member is IEvent) { + text.Append(ambience.Convert(member as IEvent)); + } else if (member is IMethod) { + text.Append(ambience.Convert(member as IMethod)); + } else if (member is IClass) { + text.Append(ambience.Convert(member as IClass)); + } else { + text.Append("unknown member "); + text.Append(member.ToString()); + } + string documentation = member.Documentation; + if (documentation != null && documentation.Length > 0) { + text.Append('\n'); + text.Append(CodeCompletionData.XmlDocumentationToText(documentation)); + } + return text.ToString(); + } + } +} diff --git a/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/TocPad.cs b/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/TocPad.cs index 259aaf7759..f3e46ee6d1 100644 --- a/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/TocPad.cs +++ b/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/TocPad.cs @@ -165,19 +165,19 @@ namespace HtmlHelp2 tocControl.EndInit(); Controls.Add(tocControl); tocControl.CreateControl(); - + tocControl.Visible = false; tocControl.BorderStyle = HxBorderStyle.HxBorderStyle_FixedSingle; tocControl.FontSource = HxFontSourceConstant.HxFontExternal; tocControl.TreeStyle = (HtmlHelp2Environment.Config.TocPictures)?TSC.HxTreeStyle_TreelinesPlusMinusPictureText:TSC.HxTreeStyle_TreelinesPlusMinusText; - + printTopic.Image = ResourcesHelper.GetBitmap("HtmlHelp2.16x16.Print.bmp"); printTopic.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText; printTopic.Text = StringParser.Parse("${res:AddIns.HtmlHelp2.PrintTopic}"); printTopic.Click += new EventHandler(this.PrintTopic); printContextMenu.Items.Add(printTopic); - + printTopicAndSubTopics.Text = StringParser.Parse("${res:AddIns.HtmlHelp2.PrintSubtopics}"); printTopicAndSubTopics.Click += new EventHandler(this.PrintTopicAndSubTopics); printContextMenu.Items.Add(printTopicAndSubTopics); @@ -286,7 +286,7 @@ namespace HtmlHelp2 filterCombobox.SelectedIndexChanged += new EventHandler(this.FilterChanged); } } - + private bool SetToc(string filterName) { try @@ -336,8 +336,10 @@ namespace HtmlHelp2 { this.UpdateControl(); - tocControl.TreeStyle = - (HtmlHelp2Environment.Config.TocPictures)?TSC.HxTreeStyle_TreelinesPlusMinusPictureText:TSC.HxTreeStyle_TreelinesPlusMinusText; + if (tocControl != null) { + tocControl.TreeStyle = + (HtmlHelp2Environment.Config.TocPictures)?TSC.HxTreeStyle_TreelinesPlusMinusPictureText:TSC.HxTreeStyle_TreelinesPlusMinusText; + } } #endregion diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs index 54ccd0ec9c..475c7c9af5 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs @@ -445,5 +445,11 @@ namespace ICSharpCode.TextEditor.Document public event EventHandler UpdateCommited; public event EventHandler TextContentChanged; + + [Conditional("DEBUG")] + internal static void ValidatePosition(IDocument document, TextLocation position) + { + document.GetLineSegment(position.Line); + } } } diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/DefaultSelection.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/DefaultSelection.cs index f766a30eb2..2f72f326a0 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/DefaultSelection.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/DefaultSelection.cs @@ -6,6 +6,7 @@ // using System; +using System.Diagnostics; using System.Drawing; namespace ICSharpCode.TextEditor.Document @@ -25,6 +26,7 @@ namespace ICSharpCode.TextEditor.Document return startPosition; } set { + DefaultDocument.ValidatePosition(document, value); startPosition = value; } } @@ -34,6 +36,7 @@ namespace ICSharpCode.TextEditor.Document return endPosition; } set { + DefaultDocument.ValidatePosition(document, value); endPosition = value; } } @@ -98,6 +101,9 @@ namespace ICSharpCode.TextEditor.Document /// public DefaultSelection(IDocument document, TextLocation startPosition, TextLocation endPosition) { + DefaultDocument.ValidatePosition(document, startPosition); + DefaultDocument.ValidatePosition(document, endPosition); + Debug.Assert(startPosition <= endPosition); this.document = document; this.startPosition = startPosition; this.endPosition = endPosition; diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/SelectionManager.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/SelectionManager.cs index 8c374e80dd..bd69659e95 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/SelectionManager.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/Selection/SelectionManager.cs @@ -17,7 +17,15 @@ namespace ICSharpCode.TextEditor.Document /// public class SelectionManager : IDisposable { - internal TextLocation selectionStart; + TextLocation selectionStart; + + internal TextLocation SelectionStart { + get { return selectionStart; } + set { + DefaultDocument.ValidatePosition(document, value); + selectionStart = value; + } + } IDocument document; TextArea textArea; internal SelectFrom selectFrom = new SelectFrom(); @@ -183,7 +191,7 @@ namespace ICSharpCode.TextEditor.Document SetSelection(new DefaultSelection(document, min, max)); // initialise selectFrom for a cursor selection if (selectFrom.where == WhereFrom.None) - selectionStart = oldPosition; //textArea.Caret.Position; + SelectionStart = oldPosition; //textArea.Caret.Position; return; } @@ -200,9 +208,9 @@ namespace ICSharpCode.TextEditor.Document newPosition.X = 0; } - if (GreaterEqPos(newPosition, selectionStart)) // selecting forward + if (GreaterEqPos(newPosition, SelectionStart)) // selecting forward { - selection.StartPosition = selectionStart; + selection.StartPosition = SelectionStart; // this handles last line selection if (selectFrom.where == WhereFrom.Gutter ) //&& newPosition.Y != oldPosition.Y) selection.EndPosition = new TextLocation(textArea.Caret.Column, textArea.Caret.Line); @@ -213,9 +221,9 @@ namespace ICSharpCode.TextEditor.Document } else { // selecting back if (selectFrom.where == WhereFrom.Gutter && selectFrom.first == WhereFrom.Gutter) { // gutter selection - selection.EndPosition = NextValidPosition(selectionStart.Y); + selection.EndPosition = NextValidPosition(SelectionStart.Y); } else { // internal text selection - selection.EndPosition = selectionStart; //selection.StartPosition; + selection.EndPosition = SelectionStart; //selection.StartPosition; } selection.StartPosition = newPosition; } @@ -257,11 +265,16 @@ namespace ICSharpCode.TextEditor.Document // this is the most logical place to reset selection starting // positions because it is always called before a new selection selectFrom.first = selectFrom.where; - selectionStart = textArea.TextView.GetLogicalPosition(mousepos.X - textArea.TextView.DrawingPosition.X, mousepos.Y - textArea.TextView.DrawingPosition.Y); - if(selectFrom.where == WhereFrom.Gutter) { - selectionStart.X = 0; + TextLocation newSelectionStart = textArea.TextView.GetLogicalPosition(mousepos.X - textArea.TextView.DrawingPosition.X, mousepos.Y - textArea.TextView.DrawingPosition.Y); + if (selectFrom.where == WhereFrom.Gutter) { + newSelectionStart.X = 0; // selectionStart.Y = -1; } + if (newSelectionStart.Line >= document.TotalNumberOfLines) { + newSelectionStart.Line = document.TotalNumberOfLines-1; + newSelectionStart.Column = document.GetLineSegment(document.TotalNumberOfLines-1).Length; + } + this.SelectionStart = newSelectionStart; ClearWithoutUpdate(); document.CommitUpdate(); diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs index 1df2d7edd4..8e652dc061 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs @@ -213,7 +213,7 @@ namespace ICSharpCode.TextEditor // the selection is from the gutter if (textArea.SelectionManager.selectFrom.where == WhereFrom.Gutter) { - if(realmousepos.Y < textArea.SelectionManager.selectionStart.Y) { + if(realmousepos.Y < textArea.SelectionManager.SelectionStart.Y) { // the selection has moved above the startpoint textArea.Caret.Position = new TextLocation(0, realmousepos.Y); } else { @@ -287,7 +287,7 @@ namespace ICSharpCode.TextEditor selection.StartPosition = minSelection; selection.EndPosition = maxSelection; - textArea.SelectionManager.selectionStart = minSelection; + textArea.SelectionManager.SelectionStart = minSelection; } // after a double-click selection, the caret is placed correctly, @@ -341,7 +341,7 @@ namespace ICSharpCode.TextEditor if (!minSelection.IsEmpty && !maxSelection.IsEmpty && textArea.SelectionManager.SelectionCollection.Count > 0) { textArea.SelectionManager.SelectionCollection[0].StartPosition = minSelection; textArea.SelectionManager.SelectionCollection[0].EndPosition = maxSelection; - textArea.SelectionManager.selectionStart = minSelection; + textArea.SelectionManager.SelectionStart = minSelection; minSelection = TextLocation.Empty; maxSelection = TextLocation.Empty; diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs index fe3f2c7572..76464ffe34 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs @@ -358,6 +358,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates // Textual content StreamWriter sr = new StreamWriter(File.Create(fileName), ParserService.DefaultFileEncoding); string fileContent = StringParser.Parse(file.Content, new string[,] { {"ProjectName", projectCreateInformation.ProjectName}, {"FileName", fileName}}); + fileContent = StringParser.Parse(fileContent); if (SharpDevelopTextEditorProperties.Instance.IndentationString != "\t") { fileContent = fileContent.Replace("\t", SharpDevelopTextEditorProperties.Instance.IndentationString); } diff --git a/src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs b/src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs index bea2f5ae6a..99c6d8acd5 100644 --- a/src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs +++ b/src/Main/Base/Project/Src/Project/Converter/LanguageConverter.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; +using System.Runtime.Serialization; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.Core; @@ -149,7 +150,11 @@ namespace ICSharpCode.SharpDevelop.Project.Converter if (!Directory.Exists(Path.GetDirectoryName(targetItem.FileName))) { Directory.CreateDirectory(Path.GetDirectoryName(targetItem.FileName)); } - ConvertFile(fileItem, targetItem); + try { + ConvertFile(fileItem, targetItem); + } catch (Exception ex) { + throw new ConversionException("Error converting " + fileItem.FileName, ex); + } } targetProjectItems.AddProjectItem(targetItem); } else { @@ -285,4 +290,27 @@ namespace ICSharpCode.SharpDevelop.Project.Converter p.SetProperty("NoWarn", null); } } + + /// + /// Exception used when converting a file fails. + /// + [Serializable] + public class ConversionException : Exception + { + public ConversionException() : base() + { + } + + public ConversionException(string message) : base(message) + { + } + + public ConversionException(string message, Exception innerException) : base(message, innerException) + { + } + + protected ConversionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } } diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs index f1c0783898..0c29ccda16 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs @@ -70,9 +70,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor public string IndentationString { get { if (indentationString == null) { - SharpDevelopTextEditorProperties p = new SharpDevelopTextEditorProperties(); - if (p.ConvertTabsToSpaces) - return new string(' ', p.IndentationSize); + if (ConvertTabsToSpaces) + return new string(' ', IndentationSize); else return "\t"; }