diff options
author | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-05-11 20:52:06 +0300 |
---|---|---|
committer | Lluis Sanchez Gual <lluis@xamarin.com> | 2015-05-11 20:52:06 +0300 |
commit | 17f1bd1313bb8c58765e159b4af77228edc48fae (patch) | |
tree | daae240491d3110ae7178153f1889934336f9817 /main/src | |
parent | 581eba3b3e89550d656594a751cfc2a1b8210640 (diff) | |
parent | 62b5da6489e7a7b71ccf2ba7de68c093b9f6e384 (diff) |
Merge remote-tracking branch 'origin/roslyn' into new-project-model
Diffstat (limited to 'main/src')
98 files changed, 1250 insertions, 506 deletions
diff --git a/main/src/addins/AspNet/MonoDevelop.AspNet.csproj b/main/src/addins/AspNet/MonoDevelop.AspNet.csproj index 3574f4f74d..90b0c0c245 100644 --- a/main/src/addins/AspNet/MonoDevelop.AspNet.csproj +++ b/main/src/addins/AspNet/MonoDevelop.AspNet.csproj @@ -212,6 +212,12 @@ <EmbeddedResource Include="Properties\MonoDevelop.AspNet.addin.xml"> <LogicalName>MonoDevelop.AspNet.addin.xml</LogicalName> </EmbeddedResource> + <EmbeddedResource Include="Templates\images\aspnet-empty-project.png"> + <LogicalName>aspnet-empty-project.png</LogicalName> + </EmbeddedResource> + <EmbeddedResource Include="Templates\images\aspnet-empty-project%402x.png"> + <LogicalName>aspnet-empty-project@2x.png</LogicalName> + </EmbeddedResource> </ItemGroup> <ItemGroup> <Compile Include="Html\HtmlSchemaService.cs" /> @@ -341,6 +347,8 @@ <Compile Include="Projects\AspNetStringTagProvider.cs" /> <Compile Include="Commands\MethodDeclarationAtCaret.cs" /> <Compile Include="Razor\Dom\RazorWorkbenchService.cs" /> + <Compile Include="Razor\RazorCSharpParserContext.cs" /> + <Compile Include="Razor\OpenRazorDocument.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> @@ -566,6 +574,7 @@ <Folder Include="Commands\" /> <Folder Include="ProjectPad\" /> <Folder Include="Templates\Projects\" /> + <Folder Include="Templates\images\" /> <Folder Include="WebForms\CSharp\" /> </ItemGroup> <Target Name="BeforeBuild"> diff --git a/main/src/addins/AspNet/Properties/MonoDevelop.AspNet.addin.xml b/main/src/addins/AspNet/Properties/MonoDevelop.AspNet.addin.xml index 34b4087a3e..c1330e822a 100644 --- a/main/src/addins/AspNet/Properties/MonoDevelop.AspNet.addin.xml +++ b/main/src/addins/AspNet/Properties/MonoDevelop.AspNet.addin.xml @@ -396,4 +396,8 @@ <Extension path="/MonoDevelop/Ide/ProjectTemplateWizards">
<Class id="MonoDevelop.AspNet.ProjectTemplateWizard" class="MonoDevelop.AspNet.Projects.AspNetProjectTemplateWizard" />
</Extension>
+
+ <Extension path="/MonoDevelop/Ide/TemplateImages">
+ <Image id="md-aspnet-empty-project" resource="aspnet-empty-project.png" />
+ </Extension>
</ExtensionModel>
diff --git a/main/src/addins/AspNet/Razor/OpenRazorDocument.cs b/main/src/addins/AspNet/Razor/OpenRazorDocument.cs new file mode 100644 index 0000000000..39613f9b67 --- /dev/null +++ b/main/src/addins/AspNet/Razor/OpenRazorDocument.cs @@ -0,0 +1,94 @@ +// +// OpenRazorDocument.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2015 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Web.Razor; +using MonoDevelop.Ide.Editor; + +namespace MonoDevelop.AspNet.Razor +{ + class OpenRazorDocument : IDisposable + { + ITextDocument document; + ChangeInfo lastChange; + + public OpenRazorDocument (ITextDocument document) + { + this.document = document; + document.TextChanging += OnTextReplacing; + } + + public void Dispose () + { + document.TextChanging -= OnTextReplacing; + if (ParseComplete != null) { + ParseComplete.Dispose (); + ParseComplete = null; + } + if (EditorParser != null) { + EditorParser.Dispose (); + EditorParser = null; + } + } + + public ITextDocument Document { + get { return document; } + } + + public string FileName { + get { return document.FileName; } + } + + public MonoDevelop.Web.Razor.EditorParserFixed.RazorEditorParser EditorParser { get; set; } + public DocumentParseCompleteEventArgs CapturedArgs { get; set; } + public AutoResetEvent ParseComplete { get; set; } + + public ChangeInfo LastTextChange { + get { return lastChange; } + } + + public void ClearLastTextChange () + { + lock (document) + lastChange = null; + } + + void OnTextReplacing (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) + { + lock (document) { + if (lastChange == null) + lastChange = new ChangeInfo (e.Offset, new System.Web.Razor.Text.SeekableTextReader ((sender as MonoDevelop.Ide.Editor.ITextDocument).Text)); + if (e.ChangeDelta > 0) { + lastChange.Length += e.InsertionLength; + } else { + lastChange.Length -= e.RemovalLength; + } + } + } + } +} + diff --git a/main/src/addins/AspNet/Razor/RazorCSharpParser.cs b/main/src/addins/AspNet/Razor/RazorCSharpParser.cs index 3f18f54fb2..6845e81dda 100644 --- a/main/src/addins/AspNet/Razor/RazorCSharpParser.cs +++ b/main/src/addins/AspNet/Razor/RazorCSharpParser.cs @@ -56,149 +56,182 @@ using MonoDevelop.Core.Text; namespace MonoDevelop.AspNet.Razor { - // TODO: Roslyn - Fix threading issues with using member variables. public class RazorCSharpParser : TypeSystemParser { - MonoDevelop.Web.Razor.EditorParserFixed.RazorEditorParser editorParser; - DocumentParseCompleteEventArgs capturedArgs; - AutoResetEvent parseComplete; - ChangeInfo lastChange; - string lastParsedFile; - MonoDevelop.Ide.Editor.ITextDocument currentDocument; - AspNetAppProjectFlavor aspProject; - DotNetProject project; - IList<MonoDevelop.Ide.Editor.ITextDocument> openDocuments; - - public IList<MonoDevelop.Ide.Editor.ITextDocument> OpenDocuments { get { return openDocuments; } } + IList<OpenRazorDocument> openDocuments; + IList<OpenRazorDocument> documentsPendingDispose; + + internal IList<OpenRazorDocument> OpenDocuments { get { return openDocuments; } } public RazorCSharpParser () { - openDocuments = new List<MonoDevelop.Ide.Editor.ITextDocument> (); + openDocuments = new List<OpenRazorDocument> (); + documentsPendingDispose = new List<OpenRazorDocument> (); IdeApp.Exited += delegate { //HACK: workaround for Mono's not shutting downs IsBackground threads in WaitAny calls - if (editorParser != null) { - DisposeCurrentParser (); - } + DisposeDocuments (documentsPendingDispose); + DisposeDocuments (openDocuments); }; } public override System.Threading.Tasks.Task<ParsedDocument> Parse (MonoDevelop.Ide.TypeSystem.ParseOptions parseOptions, CancellationToken cancellationToken) { - currentDocument = openDocuments.FirstOrDefault (d => d != null && d.FileName == parseOptions.FileName); - // We need document and project to be loaded to correctly initialize Razor Host. - this.project = parseOptions.Project as DotNetProject; - if (currentDocument == null && !TryAddDocument (parseOptions.FileName)) - return System.Threading.Tasks.Task.FromResult((ParsedDocument)new RazorCSharpParsedDocument (parseOptions.FileName, new RazorCSharpPageInfo ())); + OpenRazorDocument currentDocument = GetDocument (parseOptions.FileName); + if (currentDocument == null) + return System.Threading.Tasks.Task.FromResult ((ParsedDocument)new RazorCSharpParsedDocument (parseOptions.FileName, new RazorCSharpPageInfo ())); + + var context = new RazorCSharpParserContext (parseOptions, currentDocument); + + lock (currentDocument) { + return Parse (context, cancellationToken); + } + } + + OpenRazorDocument GetDocument (string fileName) + { + lock (this) { + DisposeDocuments (documentsPendingDispose); + + OpenRazorDocument currentDocument = openDocuments.FirstOrDefault (d => d != null && d.FileName == fileName); + // We need document and project to be loaded to correctly initialize Razor Host. + if (currentDocument == null && !TryAddDocument (fileName, out currentDocument)) + return null; + + return currentDocument; + } + } - this.aspProject = project.GetService<AspNetAppProjectFlavor> (); + void DisposeDocuments (IEnumerable<OpenRazorDocument> documents) + { + try { + foreach (OpenRazorDocument document in documents.Reverse ()) { + document.Dispose (); + documentsPendingDispose.Remove (document); + } + } catch (Exception ex) { + LoggingService.LogError ("Dispose pending Razor document error.", ex); + } + } - EnsureParserInitializedFor (parseOptions.FileName); + System.Threading.Tasks.Task<ParsedDocument> Parse (RazorCSharpParserContext context, CancellationToken cancellationToken) + { + EnsureParserInitializedFor (context); var errors = new List<Error> (); - using (var source = new SeekableTextReader (parseOptions.Content.CreateReader ())) { - var textChange = CreateTextChange (source); - var parseResult = editorParser.CheckForStructureChanges (textChange); + using (var source = new SeekableTextReader (context.Content.CreateReader ())) { + var textChange = CreateTextChange (context, source); + var parseResult = context.EditorParser.CheckForStructureChanges (textChange); if (parseResult == PartialParseResult.Rejected) { - parseComplete.WaitOne (); - if (!capturedArgs.GeneratorResults.Success) - GetRazorErrors (errors); + context.RazorDocument.ParseComplete.WaitOne (); + if (!context.CapturedArgs.GeneratorResults.Success) + GetRazorErrors (context, errors); } } - ParseHtmlDocument (errors); - CreateCSharpParsedDocument (parseOptions); - ClearLastChange (); + ParseHtmlDocument (context, errors); + CreateCSharpParsedDocument (context); + context.ClearLastTextChange (); RazorHostKind kind = RazorHostKind.WebPage; - if (editorParser.Host is WebCodeRazorHost) { + if (context.EditorParser.Host is WebCodeRazorHost) { kind = RazorHostKind.WebCode; - } else if (editorParser.Host is MonoDevelop.AspNet.Razor.Generator.PreprocessedRazorHost) { + } else if (context.EditorParser.Host is MonoDevelop.AspNet.Razor.Generator.PreprocessedRazorHost) { kind = RazorHostKind.Template; } - var model = document.GetSemanticModelAsync (cancellationToken).Result; + var model = context.AnalysisDocument.GetSemanticModelAsync (cancellationToken).Result; var pageInfo = new RazorCSharpPageInfo () { - HtmlRoot = htmlParsedDocument, - GeneratorResults = capturedArgs.GeneratorResults, - Spans = editorParser.CurrentParseTree.Flatten (), - CSharpSyntaxTree = parsedSyntaxTree, + HtmlRoot = context.HtmlParsedDocument, + GeneratorResults = context.CapturedArgs.GeneratorResults, + Spans = context.EditorParser.CurrentParseTree.Flatten (), + CSharpSyntaxTree = context.ParsedSyntaxTree, ParsedDocument = new DefaultParsedDocument ("generated.cs") { Ast = model }, - AnalysisDocument = document, - CSharpCode = csharpCode, + AnalysisDocument = context.AnalysisDocument, + CSharpCode = context.CSharpCode, Errors = errors, - FoldingRegions = GetFoldingRegions (), - Comments = comments, + FoldingRegions = GetFoldingRegions (context), + Comments = context.Comments, HostKind = kind, }; - return System.Threading.Tasks.Task.FromResult((ParsedDocument)new RazorCSharpParsedDocument (parseOptions.FileName, pageInfo)); + return System.Threading.Tasks.Task.FromResult((ParsedDocument)new RazorCSharpParsedDocument (context.FileName, pageInfo)); } - bool TryAddDocument (string fileName) + bool TryAddDocument (string fileName, out OpenRazorDocument currentDocument) { + currentDocument = null; if (string.IsNullOrEmpty (fileName)) return false; var guiDoc = IdeApp.Workbench.GetDocument (fileName); if (guiDoc != null && guiDoc.Editor != null) { - currentDocument = guiDoc.Editor; - currentDocument.TextChanging += OnTextReplacing; + currentDocument = new OpenRazorDocument (guiDoc.Editor); lock (this) { - var newDocs = new List<MonoDevelop.Ide.Editor.ITextDocument> (openDocuments); + var newDocs = new List<OpenRazorDocument> (openDocuments); newDocs.Add (currentDocument); openDocuments = newDocs; } + var closedDocument = currentDocument; guiDoc.Closed += (sender, args) => { var doc = sender as MonoDevelop.Ide.Gui.Document; if (doc.Editor != null && doc.Editor != null) { lock (this) { - openDocuments = new List<MonoDevelop.Ide.Editor.ITextDocument> (openDocuments.Where (d => d.FileName != doc.Editor.FileName)); + openDocuments = new List<OpenRazorDocument> (openDocuments.Where (d => d.FileName != doc.Editor.FileName)); } } - if (lastParsedFile == doc.FileName && editorParser != null) { - DisposeCurrentParser (); - } + TryDisposingDocument (closedDocument); + closedDocument = null; }; return true; } return false; } - void EnsureParserInitializedFor (string fileName) + void TryDisposingDocument (OpenRazorDocument document) { - if (lastParsedFile == fileName && editorParser != null) - return; + if (Monitor.TryEnter (document)) { + try { + document.Dispose (); + } finally { + Monitor.Exit (document); + } + } else { + lock (this) { + documentsPendingDispose.Add (document); + } + } + } - if (editorParser != null) - DisposeCurrentParser (); + void EnsureParserInitializedFor (RazorCSharpParserContext context) + { + if (context.EditorParser != null) + return; - CreateParserFor (fileName); + CreateParserFor (context); } - void CreateParserFor (string fileName) + void CreateParserFor (RazorCSharpParserContext context) { - editorParser = new MonoDevelop.Web.Razor.EditorParserFixed.RazorEditorParser (CreateRazorHost (fileName), fileName); + context.EditorParser = new MonoDevelop.Web.Razor.EditorParserFixed.RazorEditorParser (CreateRazorHost (context), context.FileName); - parseComplete = new AutoResetEvent (false); - editorParser.DocumentParseComplete += (sender, args) => + context.RazorDocument.ParseComplete = new AutoResetEvent (false); + context.EditorParser.DocumentParseComplete += (sender, args) => { - capturedArgs = args; - parseComplete.Set (); + context.RazorDocument.CapturedArgs = args; + context.RazorDocument.ParseComplete.Set (); }; - - lastParsedFile = fileName; } - RazorEngineHost CreateRazorHost (string fileName) + static RazorEngineHost CreateRazorHost (RazorCSharpParserContext context) { - if (project != null) { - var projectFile = project.GetProjectFile (fileName); + if (context.Project != null) { + var projectFile = context.Project.GetProjectFile (context.FileName); if (projectFile != null && projectFile.Generator == "RazorTemplatePreprocessor") { - return new MonoDevelop.AspNet.Razor.Generator.PreprocessedRazorHost (fileName) { + return new MonoDevelop.AspNet.Razor.Generator.PreprocessedRazorHost (context.FileName) { DesignTimeMode = true, EnableLinePragmas = false, }; @@ -206,15 +239,15 @@ namespace MonoDevelop.AspNet.Razor } string virtualPath = "~/Views/Default.cshtml"; - if (aspProject != null)
- virtualPath = aspProject.LocalToVirtualPath (fileName);
+ if (context.AspProject != null)
+ virtualPath = context.AspProject.LocalToVirtualPath (context.FileName);
WebPageRazorHost host = null; // Try to create host using web.config file var webConfigMap = new WebConfigurationFileMap (); - if (aspProject != null) { - var vdm = new VirtualDirectoryMapping (project.BaseDirectory.Combine ("Views"), true, "web.config"); + if (context.AspProject != null) { + var vdm = new VirtualDirectoryMapping (context.AspProject.Project.BaseDirectory.Combine ("Views"), true, "web.config"); webConfigMap.VirtualDirectories.Add ("/", vdm); } Configuration configuration; @@ -227,13 +260,13 @@ namespace MonoDevelop.AspNet.Razor //TODO: use our assemblies, not the project's var rws = configuration.GetSectionGroup (RazorWebSectionGroup.GroupName) as RazorWebSectionGroup; if (rws != null) { - host = WebRazorHostFactory.CreateHostFromConfig (rws, virtualPath, fileName); + host = WebRazorHostFactory.CreateHostFromConfig (rws, virtualPath, context.FileName); host.DesignTimeMode = true; } } if (host == null) { - host = new MvcWebPageRazorHost (virtualPath, fileName) { DesignTimeMode = true }; + host = new MvcWebPageRazorHost (virtualPath, context.FileName) { DesignTimeMode = true }; // Add default namespaces from Razor section host.NamespaceImports.Add ("System.Web.Mvc"); host.NamespaceImports.Add ("System.Web.Mvc.Ajax"); @@ -244,22 +277,9 @@ namespace MonoDevelop.AspNet.Razor return host; } - void DisposeCurrentParser () - { - editorParser.Dispose (); - editorParser = null; - parseComplete.Dispose (); - parseComplete = null; - ClearLastChange (); - } - - void ClearLastChange () - { - lastChange = null; - } - - TextChange CreateTextChange (SeekableTextReader source) + static TextChange CreateTextChange (RazorCSharpParserContext context, SeekableTextReader source) { + ChangeInfo lastChange = context.GetLastTextChange (); if (lastChange == null) return new TextChange (0, 0, new SeekableTextReader (String.Empty), 0, source.Length, source); if (lastChange.DeleteChange) @@ -269,24 +289,21 @@ namespace MonoDevelop.AspNet.Razor lastChange.AbsoluteLength, source); } - void GetRazorErrors (List<Error> errors) + static void GetRazorErrors (RazorCSharpParserContext context, List<Error> errors) { - foreach (var error in capturedArgs.GeneratorResults.ParserErrors) { + foreach (var error in context.CapturedArgs.GeneratorResults.ParserErrors) { int off = error.Location.AbsoluteIndex; if (error.Location.CharacterIndex > 0 && error.Length == 1) off--; - errors.Add (new Error (ErrorType.Error, error.Message, currentDocument.OffsetToLocation (off))); + errors.Add (new Error (ErrorType.Error, error.Message, context.Document.OffsetToLocation (off))); } } - MonoDevelop.Xml.Dom.XDocument htmlParsedDocument; - IList<Comment> comments; - - void ParseHtmlDocument (List<Error> errors) + static void ParseHtmlDocument (RazorCSharpParserContext context, List<Error> errors) { var sb = new StringBuilder (); var spanList = new List<Span> (); - comments = new List<Comment> (); + context.Comments = new List<Comment> (); Action<Span> action = (Span span) => { @@ -309,58 +326,58 @@ namespace MonoDevelop.AspNet.Razor CommentType = CommentType.Block, }; comment.Region = new MonoDevelop.Ide.Editor.DocumentRegion ( - currentDocument.OffsetToLocation (span.Start.AbsoluteIndex - comment.OpenTag.Length), - currentDocument.OffsetToLocation (span.Start.AbsoluteIndex + span.Length + comment.ClosingTag.Length)); - comments.Add (comment); + context.Document.OffsetToLocation (span.Start.AbsoluteIndex - comment.OpenTag.Length), + context.Document.OffsetToLocation (span.Start.AbsoluteIndex + span.Length + comment.ClosingTag.Length)); + context.Comments.Add (comment); } } }; - editorParser.CurrentParseTree.Accept (new CallbackVisitor (action)); + context.EditorParser.CurrentParseTree.Accept (new CallbackVisitor (action)); var parser = new MonoDevelop.Xml.Parser.XmlParser (new WebFormsRootState (), true); try { parser.Parse (new StringReader (sb.ToString ())); } catch (Exception ex) { - LoggingService.LogError ("Unhandled error parsing html in Razor document '" + (lastParsedFile ?? "") + "'", ex); + LoggingService.LogError ("Unhandled error parsing html in Razor document '" + (context.FileName ?? "") + "'", ex); } - htmlParsedDocument = parser.Nodes.GetRoot (); + context.HtmlParsedDocument = parser.Nodes.GetRoot (); errors.AddRange (parser.Errors); } - IEnumerable<FoldingRegion> GetFoldingRegions () + static IEnumerable<FoldingRegion> GetFoldingRegions (RazorCSharpParserContext context) { var foldingRegions = new List<FoldingRegion> (); - GetHtmlFoldingRegions (foldingRegions); - GetRazorFoldingRegions (foldingRegions); + GetHtmlFoldingRegions (context, foldingRegions); + GetRazorFoldingRegions (context, foldingRegions); return foldingRegions; } - void GetHtmlFoldingRegions (List<FoldingRegion> foldingRegions) + static void GetHtmlFoldingRegions (RazorCSharpParserContext context, List<FoldingRegion> foldingRegions) { - if (htmlParsedDocument != null) { - var d = new MonoDevelop.AspNet.WebForms.WebFormsParsedDocument (null, WebSubtype.Html, null, htmlParsedDocument); + if (context.HtmlParsedDocument != null) { + var d = new MonoDevelop.AspNet.WebForms.WebFormsParsedDocument (null, WebSubtype.Html, null, context.HtmlParsedDocument); foldingRegions.AddRange (d.Foldings); } } - void GetRazorFoldingRegions (List<FoldingRegion> foldingRegions) + static void GetRazorFoldingRegions (RazorCSharpParserContext context, List<FoldingRegion> foldingRegions) { var blocks = new List<Block> (); - GetBlocks (editorParser.CurrentParseTree, blocks); + GetBlocks (context.EditorParser.CurrentParseTree, blocks); foreach (var block in blocks) { - var beginLine = currentDocument.GetLineByOffset (block.Start.AbsoluteIndex); - var endLine = currentDocument.GetLineByOffset (block.Start.AbsoluteIndex + block.Length); + var beginLine = context.Document.GetLineByOffset (block.Start.AbsoluteIndex); + var endLine = context.Document.GetLineByOffset (block.Start.AbsoluteIndex + block.Length); if (beginLine != endLine) foldingRegions.Add (new FoldingRegion (RazorUtils.GetShortName (block), - new DocumentRegion (currentDocument.OffsetToLocation (block.Start.AbsoluteIndex), - currentDocument.OffsetToLocation (block.Start.AbsoluteIndex + block.Length)))); + new DocumentRegion (context.Document.OffsetToLocation (block.Start.AbsoluteIndex), + context.Document.OffsetToLocation (block.Start.AbsoluteIndex + block.Length)))); } } - void GetBlocks (Block root, IList<Block> blocks) + static void GetBlocks (Block root, IList<Block> blocks) { foreach (var block in root.Children.Where (n => n.IsBlock).Select (n => n as Block)) { if (block.Type != BlockType.Comment && block.Type != BlockType.Markup) @@ -370,37 +387,33 @@ namespace MonoDevelop.AspNet.Razor } } - SyntaxTree parsedSyntaxTree; - string csharpCode; - Microsoft.CodeAnalysis.Document document; - - void CreateCSharpParsedDocument (MonoDevelop.Ide.TypeSystem.ParseOptions parseOptions) + static void CreateCSharpParsedDocument (RazorCSharpParserContext context) { - if (parseOptions.Project == null) + if (context.Project == null) return; - csharpCode = CreateCodeFile (); - parsedSyntaxTree = CSharpSyntaxTree.ParseText (Microsoft.CodeAnalysis.Text.SourceText.From (csharpCode)); + context.CSharpCode = CreateCodeFile (context); + context.ParsedSyntaxTree = CSharpSyntaxTree.ParseText (Microsoft.CodeAnalysis.Text.SourceText.From (context.CSharpCode)); - var originalProject = TypeSystemService.GetCodeAnalysisProject (parseOptions.Project); + var originalProject = TypeSystemService.GetCodeAnalysisProject (context.Project); if (originalProject != null) { - string fileName = parseOptions.FileName + ".g.cs"; + string fileName = context.FileName + ".g.cs"; var documentId = TypeSystemService.GetDocumentId (originalProject.Id, fileName); if (documentId == null) { - document = originalProject.AddDocument ( + context.AnalysisDocument = originalProject.AddDocument ( fileName, - parsedSyntaxTree?.GetRoot ()); + context.ParsedSyntaxTree?.GetRoot ()); } else { - document = TypeSystemService.GetCodeAnalysisDocument (documentId); + context.AnalysisDocument = TypeSystemService.GetCodeAnalysisDocument (documentId); } } } - string CreateCodeFile () + static string CreateCodeFile (RazorCSharpParserContext context) { - var unit = capturedArgs.GeneratorResults.GeneratedCode; - System.CodeDom.Compiler.CodeDomProvider provider = project != null - ? project.LanguageBinding.GetCodeDomProvider () + var unit = context.CapturedArgs.GeneratorResults.GeneratedCode; + System.CodeDom.Compiler.CodeDomProvider provider = context.Project != null + ? context.Project.LanguageBinding.GetCodeDomProvider () : new Microsoft.CSharp.CSharpCodeProvider (); using (var sw = new StringWriter ()) { provider.GenerateCodeFromCompileUnit (unit, sw, new System.CodeDom.Compiler.CodeGeneratorOptions () { @@ -413,17 +426,6 @@ namespace MonoDevelop.AspNet.Razor return sw.ToString (); } } - - void OnTextReplacing (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) - { - if (lastChange == null) - lastChange = new ChangeInfo (e.Offset, new SeekableTextReader((sender as MonoDevelop.Ide.Editor.ITextDocument).Text)); - if (e.ChangeDelta > 0) { - lastChange.Length += e.InsertionLength; - } else { - lastChange.Length -= e.RemovalLength; - } - } } class ChangeInfo diff --git a/main/src/addins/AspNet/Razor/RazorCSharpParserContext.cs b/main/src/addins/AspNet/Razor/RazorCSharpParserContext.cs new file mode 100644 index 0000000000..133c48235c --- /dev/null +++ b/main/src/addins/AspNet/Razor/RazorCSharpParserContext.cs @@ -0,0 +1,100 @@ +// +// RazorCSharpParserContext.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2015 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Web.Razor; +using Microsoft.CodeAnalysis; +using MonoDevelop.AspNet.Projects; +using MonoDevelop.Core.Text; +using MonoDevelop.Ide.Editor; +using MonoDevelop.Ide.TypeSystem; +using MonoDevelop.Projects; +using MonoDevelop.Xml.Dom; + +namespace MonoDevelop.AspNet.Razor +{ + class RazorCSharpParserContext + { + MonoDevelop.Ide.TypeSystem.ParseOptions parseOptions; + OpenRazorDocument razorDocument; + + public RazorCSharpParserContext (MonoDevelop.Ide.TypeSystem.ParseOptions parseOptions, OpenRazorDocument razorDocument) + { + this.parseOptions = parseOptions; + this.razorDocument = razorDocument; + } + + public DotNetProject Project { + get { return parseOptions.Project as DotNetProject; } + } + + public AspNetAppProjectFlavor AspProject { + get { return parseOptions.Project.As<AspNetAppProjectFlavor> (); } + } + + public string FileName { + get { return parseOptions.FileName; } + } + + public ITextSource Content { + get { return parseOptions.Content; } + } + + public ITextDocument Document { + get { return razorDocument.Document; } + } + + public OpenRazorDocument RazorDocument { + get { return razorDocument; } + } + + public SyntaxTree ParsedSyntaxTree { get; set; } + public string CSharpCode { get; set; } + public Microsoft.CodeAnalysis.Document AnalysisDocument { get; set; } + public XDocument HtmlParsedDocument { get; set; } + public IList<Comment> Comments { get; set; } + public MonoDevelop.Web.Razor.EditorParserFixed.RazorEditorParser EditorParser { + get { return razorDocument.EditorParser; } + set { razorDocument.EditorParser = value; } + } + + public DocumentParseCompleteEventArgs CapturedArgs { + get { return razorDocument.CapturedArgs; } + } + + public ChangeInfo GetLastTextChange () + { + return razorDocument.LastTextChange; + } + + public void ClearLastTextChange () + { + razorDocument.ClearLastTextChange (); + } + } +} + diff --git a/main/src/addins/AspNet/Templates/Projects/EmptyMvcProject.xpt.xml b/main/src/addins/AspNet/Templates/Projects/EmptyMvcProject.xpt.xml index 0f77668c3d..b2bb7d0318 100644 --- a/main/src/addins/AspNet/Templates/Projects/EmptyMvcProject.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/EmptyMvcProject.xpt.xml @@ -8,6 +8,7 @@ <_Name>Empty ASP.NET MVC Project</_Name> <Category>other/aspnet/general</Category> <Icon>md-project-web</Icon> + <Image id="md-aspnet-empty-project" /> <LanguageName>C#</LanguageName> <_Description>Creates an empty ASP.NET MVC Web Project.</_Description> </TemplateConfiguration> diff --git a/main/src/addins/AspNet/Templates/Projects/EmptyProject.xpt.xml b/main/src/addins/AspNet/Templates/Projects/EmptyProject.xpt.xml index c3ca7d3f05..80e5b1f6ae 100644 --- a/main/src/addins/AspNet/Templates/Projects/EmptyProject.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/EmptyProject.xpt.xml @@ -8,6 +8,7 @@ <_Name>Empty ASP.NET Project</_Name> <Category>other/aspnet/general</Category> <Icon>md-project-web</Icon> + <Image id="md-aspnet-empty-project" /> <LanguageName>C#</LanguageName> <_Description>Creates an empty ASP.NET Web Application project.</_Description> </TemplateConfiguration> diff --git a/main/src/addins/AspNet/Templates/Projects/MvcProject.xpt.xml b/main/src/addins/AspNet/Templates/Projects/MvcProject.xpt.xml index 3e94df04dc..05398f1b7e 100644 --- a/main/src/addins/AspNet/Templates/Projects/MvcProject.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/MvcProject.xpt.xml @@ -8,6 +8,7 @@ <_Name>ASP.NET MVC Project</_Name>
<Category>other/aspnet/general</Category>
<Icon>md-project-web</Icon>
+ <Image id="md-aspnet-empty-project" />
<LanguageName>C#</LanguageName>
<_Description>Creates an ASP.NET MVC Web Project.</_Description>
</TemplateConfiguration>
diff --git a/main/src/addins/AspNet/Templates/Projects/MvcProjectWithUnitTest.xpt.xml b/main/src/addins/AspNet/Templates/Projects/MvcProjectWithUnitTest.xpt.xml index 215f63abe6..461e8a19a3 100644 --- a/main/src/addins/AspNet/Templates/Projects/MvcProjectWithUnitTest.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/MvcProjectWithUnitTest.xpt.xml @@ -8,6 +8,7 @@ <_Name>ASP.NET MVC Project with Unit Tests</_Name>
<Category>other/aspnet/general</Category>
<Icon>md-project-web</Icon>
+ <Image id="md-aspnet-empty-project" />
<LanguageName>C#</LanguageName>
<_Description>Creates an ASP.NET MVC Web Project with a Unit Test Project.</_Description>
</TemplateConfiguration>
diff --git a/main/src/addins/AspNet/Templates/Projects/MvcRazorProject.xpt.xml b/main/src/addins/AspNet/Templates/Projects/MvcRazorProject.xpt.xml index 16062d0e10..94f7e6a3a9 100644 --- a/main/src/addins/AspNet/Templates/Projects/MvcRazorProject.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/MvcRazorProject.xpt.xml @@ -8,6 +8,7 @@ <_Name>ASP.NET MVC Razor Project</_Name> <Category>other/aspnet/general</Category> <Icon>md-project-web</Icon> + <Image id="md-aspnet-empty-project" /> <LanguageName>C#</LanguageName> <_Description>Creates an ASP.NET MVC Project with Razor Views.</_Description> <GroupId>md-mvc-razor-project</GroupId> diff --git a/main/src/addins/AspNet/Templates/Projects/MvcRazorProjectWithUnitTest.xpt.xml b/main/src/addins/AspNet/Templates/Projects/MvcRazorProjectWithUnitTest.xpt.xml index c1cfbc74b7..abda80aecb 100644 --- a/main/src/addins/AspNet/Templates/Projects/MvcRazorProjectWithUnitTest.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/MvcRazorProjectWithUnitTest.xpt.xml @@ -8,6 +8,7 @@ <_Name>ASP.NET MVC Razor Project with Unit Tests</_Name> <Category>other/aspnet/general</Category> <Icon>md-project-web</Icon> + <Image id="md-aspnet-empty-project" /> <LanguageName>C#</LanguageName> <_Description>Creates an ASP.NET MVC Web Project with Razor Views and a Unit Test Project.</_Description> </TemplateConfiguration> diff --git a/main/src/addins/AspNet/Templates/Projects/WebApplication.xpt.xml b/main/src/addins/AspNet/Templates/Projects/WebApplication.xpt.xml index 89e884d594..0fe41abce8 100644 --- a/main/src/addins/AspNet/Templates/Projects/WebApplication.xpt.xml +++ b/main/src/addins/AspNet/Templates/Projects/WebApplication.xpt.xml @@ -8,6 +8,7 @@ <_Name>ASP.NET Project</_Name> <Category>other/aspnet/general</Category> <Icon>md-project-web</Icon> + <Image id="md-aspnet-empty-project" /> <LanguageName>C#</LanguageName> <_Description>Creates a new ASP.NET Web Application project.</_Description> </TemplateConfiguration> diff --git a/main/src/addins/AspNet/Templates/WebForms/MasterPage-CodeBehind.xft.xml b/main/src/addins/AspNet/Templates/WebForms/MasterPage-CodeBehind.xft.xml index 7a5848aa9e..8163d9d939 100644 --- a/main/src/addins/AspNet/Templates/WebForms/MasterPage-CodeBehind.xft.xml +++ b/main/src/addins/AspNet/Templates/WebForms/MasterPage-CodeBehind.xft.xml @@ -25,7 +25,7 @@ <body> <div id="container"> <form runat="server"> - <asp:contentplaceholder id="contentPlaceHolder" runat="server" /> + <asp:ContentPlaceHolder id="contentPlaceHolder" runat="server" /> </form> </div> </body> diff --git a/main/src/addins/AspNet/Templates/WebForms/MasterPage-Empty.xft.xml b/main/src/addins/AspNet/Templates/WebForms/MasterPage-Empty.xft.xml index 9c3e845d88..bf173a6548 100644 --- a/main/src/addins/AspNet/Templates/WebForms/MasterPage-Empty.xft.xml +++ b/main/src/addins/AspNet/Templates/WebForms/MasterPage-Empty.xft.xml @@ -25,7 +25,7 @@ <body> <div id="container"> <form runat="server"> - <asp:contentplaceholder id="contentPlaceHolder" runat="server" /> + <asp:ContentPlaceHolder id="contentPlaceHolder" runat="server" /> </form> </div> </body> diff --git a/main/src/addins/AspNet/Templates/images/aspnet-empty-project.png b/main/src/addins/AspNet/Templates/images/aspnet-empty-project.png Binary files differnew file mode 100644 index 0000000000..3fffa8a82b --- /dev/null +++ b/main/src/addins/AspNet/Templates/images/aspnet-empty-project.png diff --git a/main/src/addins/AspNet/Templates/images/aspnet-empty-project@2x.png b/main/src/addins/AspNet/Templates/images/aspnet-empty-project@2x.png Binary files differnew file mode 100644 index 0000000000..6451bfae20 --- /dev/null +++ b/main/src/addins/AspNet/Templates/images/aspnet-empty-project@2x.png diff --git a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs index 13d884c970..82a31a4c93 100644 --- a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs +++ b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs @@ -171,7 +171,7 @@ namespace MonoDevelop.AspNet.Tests.Razor public override System.Threading.Tasks.Task<ParsedDocument> Parse (ParseOptions parseOptions, System.Threading.CancellationToken cancellationToken)
{
Doc.Editor.FileName = parseOptions.FileName;
- OpenDocuments.Add (Doc.Editor);
+ OpenDocuments.Add (new OpenRazorDocument (Doc.Editor));
return base.Parse (parseOptions, cancellationToken);
}
}
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.JSon/JSonIndentEngine.cs b/main/src/addins/CSharpBinding/MonoDevelop.JSon/JSonIndentEngine.cs index 320000b80b..f28c2ea193 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.JSon/JSonIndentEngine.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.JSon/JSonIndentEngine.cs @@ -56,11 +56,26 @@ namespace MonoDevelop.JSon Reset (); } + JSonIndentEngine (JSonIndentEngine jSonIndentEngine) + { + this.editor = jSonIndentEngine.editor; + this.ctx = jSonIndentEngine.ctx; + this.offset = jSonIndentEngine.offset; + this.line = jSonIndentEngine.line; + this.column = jSonIndentEngine.column; + this.thisLineIndent = jSonIndentEngine.thisLineIndent.Clone (); + this.nextLineIndent = jSonIndentEngine.nextLineIndent.Clone (); + this.currentIndent = jSonIndentEngine.currentIndent != null ? new StringBuilder (jSonIndentEngine.currentIndent.ToString ()) : null; + this.previousChar = jSonIndentEngine.previousChar; + this.isLineStart = jSonIndentEngine.isLineStart; + this.isInString = jSonIndentEngine.isInString; + } + #region IStateMachineIndentEngine implementation public IStateMachineIndentEngine Clone () { - return (IStateMachineIndentEngine)MemberwiseClone (); + return new JSonIndentEngine (this); } public bool IsInsidePreprocessorDirective { @@ -228,6 +243,8 @@ namespace MonoDevelop.JSon } SourceText sourceText; + JSonIndentEngine jSonIndentEngine; + public SourceText Document { get { return sourceText ?? (sourceText = new MonoDevelopSourceText (editor)); diff --git a/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project.png b/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project.png Binary files differindex c351f0cfa0..976dbfb101 100644 --- a/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project.png +++ b/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project.png diff --git a/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project@2x.png b/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project@2x.png Binary files differindex 1f1f31023f..d30d817102 100644 --- a/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project@2x.png +++ b/main/src/addins/Deployment/MonoDevelop.Deployment/templates/images/packaging-project@2x.png diff --git a/main/src/addins/MacPlatform/MacInterop/Keychain.cs b/main/src/addins/MacPlatform/MacInterop/Keychain.cs index e0e5dfd886..a3717ebeb2 100644 --- a/main/src/addins/MacPlatform/MacInterop/Keychain.cs +++ b/main/src/addins/MacPlatform/MacInterop/Keychain.cs @@ -553,12 +553,15 @@ namespace MonoDevelop.MacInterop 0, null, (uint) path.Length, path, (ushort) uri.Port, protocol, auth, out passwordLength, out passwordData, ref item); - if (result != OSStatus.Ok) - return null; - - var username = GetUsernameFromKeychainItemRef (item); + try { + if (result != OSStatus.Ok) + return null; - return Tuple.Create (username, Marshal.PtrToStringAuto (passwordData, (int) passwordLength)); + var username = GetUsernameFromKeychainItemRef (item); + return Tuple.Create (username, Marshal.PtrToStringAuto (passwordData, (int) passwordLength)); + } finally { + CFRelease (item); + } } public static string FindInternetPassword (Uri uri) @@ -591,6 +594,64 @@ namespace MonoDevelop.MacInterop return Marshal.PtrToStringAuto (passwordData, (int) passwordLength); } + + public static void RemoveInternetPassword (Uri uri) + { + var pathStr = string.Join (string.Empty, uri.Segments); + byte[] path = pathStr.Length > 0 ? Encoding.UTF8.GetBytes (pathStr.Substring (1)) : new byte[0]; // don't include the leading '/' + byte[] user = Encoding.UTF8.GetBytes (Uri.UnescapeDataString (uri.UserInfo)); + byte[] host = Encoding.UTF8.GetBytes (uri.Host); + var auth = GetSecAuthenticationType (uri.Query); + var protocol = GetSecProtocolType (uri.Scheme); + IntPtr passwordData = IntPtr.Zero; + IntPtr item = IntPtr.Zero; + uint passwordLength = 0; + + // Look for an internet password for the given protocol and auth mechanism + var result = SecKeychainFindInternetPassword (CurrentKeychain, (uint) host.Length, host, 0, null, + (uint) user.Length, user, (uint) path.Length, path, (ushort) uri.Port, + protocol, auth, out passwordLength, out passwordData, ref item); + + // Fall back to looking for a password for SecProtocolType.Any && SecAuthenticationType.Any + if (result == OSStatus.ItemNotFound && protocol != SecProtocolType.Any) + result = SecKeychainFindInternetPassword (CurrentKeychain, (uint) host.Length, host, 0, null, + (uint) user.Length, user, (uint) path.Length, path, (ushort) uri.Port, + 0, auth, out passwordLength, out passwordData, ref item); + + try { + if (result != OSStatus.Ok) + return; + + SecKeychainItemDelete (item); + } finally { + CFRelease (item); + } + } + + public static void RemoveInternetUserNameAndPassword (Uri uri) + { + var pathStr = string.Join (string.Empty, uri.Segments); + byte[] path = pathStr.Length > 0 ? Encoding.UTF8.GetBytes (pathStr.Substring (1)) : new byte[0]; // don't include the leading '/' + byte[] host = Encoding.UTF8.GetBytes (uri.Host); + var auth = GetSecAuthenticationType (uri.Query); + IntPtr passwordData; + IntPtr item = IntPtr.Zero; + uint passwordLength = 0; + + var result = SecKeychainFindInternetPassword ( + CurrentKeychain, (uint) host.Length, host, 0, null, + 0, null, (uint) path.Length, path, (ushort) uri.Port, + GetSecProtocolType (uri.Scheme), auth, out passwordLength, out passwordData, ref item); + + try { + if (result != OSStatus.Ok) + return; + + SecKeychainItemDelete (item); + } finally { + CFRelease (item); + } + } } enum SecItemClass : uint diff --git a/main/src/addins/MacPlatform/MacKeychainPasswordProvider.cs b/main/src/addins/MacPlatform/MacKeychainPasswordProvider.cs index b05c492102..54a68252a3 100644 --- a/main/src/addins/MacPlatform/MacKeychainPasswordProvider.cs +++ b/main/src/addins/MacPlatform/MacKeychainPasswordProvider.cs @@ -52,5 +52,15 @@ namespace MonoDevelop.MacIntegration { return Keychain.FindInternetUserNameAndPassword (url); } + + public void RemoveWebPassword (Uri uri) + { + Keychain.RemoveInternetPassword (uri); + } + + public void RemoveWebUserNameAndPassword (Uri uri) + { + Keychain.RemoveInternetUserNameAndPassword (uri); + } } } diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs index 184c6b6f32..4e288b0027 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs +++ b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/debug/Value.cs @@ -745,6 +745,16 @@ namespace Microsoft.Samples.Debugging.CorDebug return sdims;
}
+ public int[] GetBaseIndicies()
+ {
+ Debug.Assert(Rank!=0);
+ uint[] baseIndicies = new uint[Rank];
+ m_arrayVal.GetBaseIndicies((uint)baseIndicies.Length,baseIndicies);
+
+ int[] sdims = Array.ConvertAll<uint,int>( baseIndicies, delegate(uint u) { return (int)u; } );
+ return sdims;
+ }
+
public CorValue GetElement(int[] indices)
{
Debug.Assert(indices!=null);
diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/ArrayAdaptor.cs b/main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/ArrayAdaptor.cs index 52bec05b19..1c25fde654 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/ArrayAdaptor.cs +++ b/main/src/addins/MonoDevelop.Debugger.Win32/MonoDevelop.Debugger.Win32/ArrayAdaptor.cs @@ -47,7 +47,11 @@ namespace MonoDevelop.Debugger.Win32 public int[] GetLowerBounds () { - return new int[array != null ? array.Rank : 0]; + if (array != null && array.HasBaseIndicies) { + return array.GetBaseIndicies (); + } else { + return new int[GetDimensions ().Length]; + } } public int[] GetDimensions () diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/MonoDevelop.Debugger.Tests.NonUserCodeTestLib.csproj b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/MonoDevelop.Debugger.Tests.NonUserCodeTestLib.csproj new file mode 100644 index 0000000000..5de4c16d4a --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/MonoDevelop.Debugger.Tests.NonUserCodeTestLib.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{8AFA4FB4-BD2D-478F-942B-7AE3451535BB}</ProjectGuid> + <OutputType>Library</OutputType> + <RootNamespace>MonoDevelop.Debugger.Tests.NonUserCodeTestLib</RootNamespace> + <AssemblyName>MonoDevelop.Debugger.Tests.NonUserCodeTestLib</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG;</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>full</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <Compile Include="NonUserCodeClass.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/NonUserCodeClass.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/NonUserCodeClass.cs new file mode 100644 index 0000000000..89c1f30614 --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.NonUserCodeTestLib/NonUserCodeClass.cs @@ -0,0 +1,48 @@ +// +// MyClass.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Threading.Tasks; + +namespace MonoDevelop.Debugger.Tests.NonUserCodeTestLib +{ + public class NonUserCodeClass + { + // Trick with NonUserCode is that we are referencing output.dll instead of project + // in MonoDevelop.Debugger.Tests.TestApp. + + //We must delay exception so stacktrace is not getting back to user code(in TestApp) + public static void ThrowDelayedHandledException () + { + Task.Delay (100).ContinueWith ((obj) => { + try { + throw new Exception ("3913936e-3f89-4f07-a863-7275aaaa5fc9"); + } catch { + } + }); + } + } +} + diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/BreakpointsAndStepping.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/BreakpointsAndStepping.cs index 392a6ea640..03788c701c 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/BreakpointsAndStepping.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/BreakpointsAndStepping.cs @@ -30,7 +30,8 @@ using System.Threading; using System.Threading.Tasks;
using System.Net.Sockets;
using System.Diagnostics;
-
+using MonoDevelop.Debugger.Tests.NonUserCodeTestLib; + namespace MonoDevelop.Debugger.Tests.TestApp
{
public class BreakpointsAndStepping
@@ -417,6 +418,16 @@ namespace MonoDevelop.Debugger.Tests.TestApp }
}
+ /// <summary>
+ /// Bug 9615
+ /// </summary>
+ public void CatchpointIgnoreExceptionsInNonUserCode () + {
+ NonUserCodeClass.ThrowDelayedHandledException ();
+ Thread.Sleep (200);
+ var a = 0;/*999b8a83-8c32-4640-a8e1-f74309cda79c*/
+ }
+
public void SimpleMethod ()
{
/*f4e3a214-229e-44dd-9da2-db82ddfbec11*/
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/MonoDevelop.Debugger.Tests.TestApp.csproj b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/MonoDevelop.Debugger.Tests.TestApp.csproj index d315a84c31..811da424a7 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/MonoDevelop.Debugger.Tests.TestApp.csproj +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/MonoDevelop.Debugger.Tests.TestApp.csproj @@ -36,6 +36,9 @@ <Reference Include="System" /> <Reference Include="System.Xml" /> <Reference Include="Microsoft.CSharp" /> + <Reference Include="MonoDevelop.Debugger.Tests.NonUserCodeTestLib"> + <HintPath>..\MonoDevelop.Debugger.Tests.NonUserCodeTestLib\bin\Debug\MonoDevelop.Debugger.Tests.NonUserCodeTestLib.dll</HintPath> + </Reference> </ItemGroup> <ItemGroup> <Compile Include="Main.cs" /> @@ -45,4 +48,11 @@ <Compile Include="AdvancedEvaluation.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <ProjectReference Include="..\MonoDevelop.Debugger.Tests.NonUserCodeTestLib\MonoDevelop.Debugger.Tests.NonUserCodeTestLib.csproj"> + <Project>{8AFA4FB4-BD2D-478F-942B-7AE3451535BB}</Project> + <Name>MonoDevelop.Debugger.Tests.NonUserCodeTestLib</Name> + <Private>False</Private> + </ProjectReference> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/TestEvaluation.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/TestEvaluation.cs index ad7c73796e..05a6983306 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/TestEvaluation.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests.TestApp/TestEvaluation.cs @@ -105,6 +105,8 @@ namespace MonoDevelop.Debugger.Tests.TestApp var withToString = new WithToString (); var numbersArrays = new int [2][]; + numbersArrays [0] = new int [10]; + numbersArrays [0] [7] = 24; var numbersMulti = new int [3, 4, 5]; var ops1 = new BinaryOperatorOverrides (1); @@ -139,6 +141,17 @@ namespace MonoDevelop.Debugger.Tests.TestApp var richObject = new RichClass (); byte[] nulledByteArray = null; + var arrayWithLowerBounds = Array.CreateInstance (typeof(int), new int[] { 3, 4, 5 }, new int[] { 5, 4, 3 }); + int m = 100; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 5; k++) { + numbersMulti.SetValue (m, i, j, k); + arrayWithLowerBounds.SetValue (m++, i + 5, j + 4, k + 3); + } + } + } + Console.WriteLine (n); /*break*/ } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/BreakpointsAndSteppingTests.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/BreakpointsAndSteppingTests.cs index e48ecb8a08..f6140c6ce9 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/BreakpointsAndSteppingTests.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/BreakpointsAndSteppingTests.cs @@ -883,6 +883,28 @@ namespace MonoDevelop.Debugger.Tests Assert.IsFalse (Session.ActiveThread.Backtrace.GetFrame (1).IsExternalCode);
}
+ [Test]
+ public void CatchpointIgnoreExceptionsInNonUserCodeTest ()
+ {
+ //It seems CorDebugger has different definition of what is user code and what is not.
+ IgnoreCorDebugger ("CorDebugger: TODO");
+
+ InitializeTest ();
+ Session.Options.ProjectAssembliesOnly = true;
+ AddBreakpoint ("999b8a83-8c32-4640-a8e1-f74309cda79c");
+ AddCatchpoint ("System.Exception", true);
+ StartTest ("CatchpointIgnoreExceptionsInNonUserCode");
+ CheckPosition ("999b8a83-8c32-4640-a8e1-f74309cda79c");
+
+ InitializeTest ();
+ Session.Options.ProjectAssembliesOnly = false;
+ AddCatchpoint ("System.Exception", true);
+ AddBreakpoint ("999b8a83-8c32-4640-a8e1-f74309cda79c");
+ StartTest ("CatchpointIgnoreExceptionsInNonUserCode");
+ WaitStop (2000);
+ Assert.AreEqual ("3913936e-3f89-4f07-a863-7275aaaa5fc9", Session.ActiveThread.Backtrace.GetFrame (0).GetException ().Message);
+ }
+
[Test] public void ConditionalBreakpoints ()
{
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/DebugTests.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/DebugTests.cs index 85f6cfc2ea..033e45bb70 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/DebugTests.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/DebugTests.cs @@ -283,6 +283,13 @@ namespace MonoDevelop.Debugger.Tests return Frame.GetExpressionValue (exp, true).Sync (); } + public void WaitStop (int miliseconds) + { + if (!targetStoppedEvent.WaitOne (miliseconds)) { + Assert.Fail ("WaitStop failure: Target stop timeout"); + } + } + public bool CheckPosition (string guid, int offset = 0, string statement = null, bool silent = false) { if (!targetStoppedEvent.WaitOne (3000)) { diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/EvaluationTests.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/EvaluationTests.cs index 8da5bb30d1..b58652d76f 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/EvaluationTests.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/EvaluationTests.cs @@ -1334,6 +1334,10 @@ namespace MonoDevelop.Debugger.Tests Assert.AreEqual ("(null)", val.Value); Assert.AreEqual ("byte[]", val.TypeName); Assert.IsTrue (val.IsNull); + + val = Eval ("arrayWithLowerBounds"); + Assert.AreEqual ("int[,,]", val.TypeName); + Assert.AreEqual ("{int[3,4,5]}", val.Value); } [Test] @@ -1987,5 +1991,32 @@ namespace MonoDevelop.Debugger.Tests Assert.AreEqual ("First Int:32 Second Int:43", val.Value); } } + + [Test] + public void ArrayTests () + { + ObjectValue val; + + val = Eval ("numbersMulti[1,2,3]"); + Assert.AreEqual ("int", val.TypeName); + Assert.AreEqual ("133", val.Value); + + val = Eval ("numbersArrays[0][7]"); + Assert.AreEqual ("int", val.TypeName); + Assert.AreEqual ("24", val.Value); + + val = Eval ("arrayWithLowerBounds[5,6,7]"); + Assert.AreEqual ("int", val.TypeName); + Assert.AreEqual ("114", val.Value); + + if (AllowTargetInvokes) { + val = Eval ("arrayWithLowerBounds.GetValue(5,6,7)"); + Assert.AreEqual ("int", val.TypeName); + Assert.AreEqual ("114", val.Value); + } + + var children = Eval ("arrayWithLowerBounds").GetAllChildrenSync (); + Assert.AreEqual ("[5, ...]", children [0].Name); + } } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs index 18895f3aef..f629716f8b 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs @@ -1351,7 +1351,16 @@ namespace MonoDevelop.Debugger var entry = (Entry) args.Editable; var val = store.GetValue (it, ObjectColumn) as ObjectValue; - string strVal = val != null ? val.Value : null; + string strVal = null; + if (val != null) { + if (val.TypeName == "string") { + var opt = frame.DebuggerSession.Options.EvaluationOptions.Clone (); + opt.EllipsizeStrings = false; + strVal = '"' + Mono.Debugging.Evaluation.ExpressionEvaluator.EscapeString ((string)val.GetRawValue (opt)) + '"'; + } else { + strVal = val.Value; + } + } if (!string.IsNullOrEmpty (strVal)) entry.Text = strVal; @@ -1833,14 +1842,18 @@ namespace MonoDevelop.Debugger PreviewWindowManager.DestroyWindow (); } - bool retval = base.OnButtonPressEvent (evnt); //HACK: show context menu in release event instead of show event to work around gtk bug if (evnt.TriggersContextMenu ()) { // ShowPopup (evnt); + if (!this.IsClickedNodeSelected ((int)evnt.X, (int)evnt.Y)) { + //pass click to base so it can update the selection + //unless the node is already selected, in which case we don't want to change the selection(deselect multi selection) + base.OnButtonPressEvent (evnt); + } return true; + } else { + return base.OnButtonPressEvent (evnt); } - - return retval; } protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt) @@ -1921,6 +1934,14 @@ namespace MonoDevelop.Debugger string value = (string) store.GetValue (iter, ValueColumn); string name = (string) store.GetValue (iter, NameColumn); string type = (string) store.GetValue (iter, TypeColumn); + if (type == "string") { + var objVal = store.GetValue (iter, ObjectColumn) as ObjectValue; + if (objVal != null) { + var opt = frame.DebuggerSession.Options.EvaluationOptions.Clone (); + opt.EllipsizeStrings = false; + value = '"' + Mono.Debugging.Evaluation.ExpressionEvaluator.EscapeString ((string)objVal.GetRawValue (opt)) + '"'; + } + } maxValue = Math.Max (maxValue, value.Length); maxName = Math.Max (maxName, name.Length); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSourceViewModelChecker.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSourceViewModelChecker.cs index 2dfa1effe4..dd60e30ca6 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSourceViewModelChecker.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSourceViewModelChecker.cs @@ -93,6 +93,7 @@ namespace MonoDevelop.PackageManagement } catch (WebException ex) {
return CreatePackageSourceViewModelCheckedEventArgs (packageSource, ex);
} catch (Exception ex) {
+ LogPackageSourceException (packageSource, ex);
return new PackageSourceViewModelCheckedEventArgs (packageSource, ex.Message);
}
}
@@ -159,7 +160,7 @@ namespace MonoDevelop.PackageManagement }
}
- LoggingService.LogInfo (String.Format ("Package source '{0}' returned exception.", packageSource.SourceUrl), ex);
+ LogPackageSourceException (packageSource, ex);
switch (ex.Status) {
case WebExceptionStatus.ConnectFailure:
@@ -174,6 +175,11 @@ namespace MonoDevelop.PackageManagement return new PackageSourceViewModelCheckedEventArgs (packageSource, errorMessage);
}
+ void LogPackageSourceException (PackageSourceViewModel packageSource, Exception ex)
+ {
+ LoggingService.LogInfo (String.Format ("Package source '{0}' returned exception.", packageSource.SourceUrl), ex);
+ }
+
void OnPackageSourceChecked (object sender, ITask<PackageSourceViewModelCheckedEventArgs> task)
{
PackageSourceViewModelCheckedEventArgs eventArgs = CreateEventArgs (task);
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.addin.xml b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.addin.xml index 8c13a84ff1..05d7938303 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.addin.xml +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.addin.xml @@ -162,11 +162,7 @@ <Extension path = "/MonoDevelop/SourceEditor2/EditorFactory"> <Class id = "SourceEditor" class="MonoDevelop.SourceEditor.EditorFactory" /> </Extension> - - <Extension path = "/MonoDevelop/Ide/TextEditorExtensions"> - <Class fileExtensions = ".json" class = "MonoDevelop.SourceEditor.JSon.JSonTextEditorExtension" /> - </Extension> - + <Extension path = "/MonoDevelop/Core/UserDataMigration"> <!-- 2.4 --> <Migration sourceVersion="2.4" kind="UserData" path="syntaxmodes" targetPath="HighlightingSchemes" isDirectory="true" /> diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/DebugValueTooltipProvider.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/DebugValueTooltipProvider.cs index 8f73a75308..4f28711890 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/DebugValueTooltipProvider.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/DebugValueTooltipProvider.cs @@ -46,7 +46,6 @@ namespace MonoDevelop.SourceEditor { class DebugValueTooltipProvider: TooltipProvider, IDisposable { - Dictionary<string,ObjectValue> cachedValues = new Dictionary<string,ObjectValue> (); DebugValueWindow tooltip; public DebugValueTooltipProvider () @@ -62,9 +61,6 @@ namespace MonoDevelop.SourceEditor void CurrentFrameChanged (object sender, EventArgs e) { - // Clear the cached values every time the current frame changes - cachedValues.Clear (); - if (tooltip != null) tooltip.Hide (); } @@ -123,17 +119,13 @@ namespace MonoDevelop.SourceEditor if (string.IsNullOrEmpty (expression)) return null; - - ObjectValue val; - if (!cachedValues.TryGetValue (expression, out val)) { - var options = DebuggingService.DebuggerSession.EvaluationOptions.Clone (); - options.AllowMethodEvaluation = true; - options.AllowTargetInvoke = true; - - val = frame.GetExpressionValue (expression, options); - cachedValues [expression] = val; - } - + + var options = DebuggingService.DebuggerSession.EvaluationOptions.Clone (); + options.AllowMethodEvaluation = true; + options.AllowTargetInvoke = true; + + var val = frame.GetExpressionValue (expression, options); + if (val == null || val.IsUnknown || val.IsNotSupported) return null; @@ -175,6 +167,8 @@ namespace MonoDevelop.SourceEditor { DebuggingService.CurrentFrameChanged -= CurrentFrameChanged; DebuggingService.DebugSessionStarted -= DebugSessionStarted; + if (DebuggingService.DebuggerSession != null) + DebuggingService.DebuggerSession.TargetExited -= TargetProcessExited; } #endregion } diff --git a/main/src/addins/NUnit/Gui/TestResultsPad.cs b/main/src/addins/NUnit/Gui/TestResultsPad.cs index b042182d61..610f011ba1 100644 --- a/main/src/addins/NUnit/Gui/TestResultsPad.cs +++ b/main/src/addins/NUnit/Gui/TestResultsPad.cs @@ -45,6 +45,7 @@ using MonoDevelop.Components; using System.Threading; using MonoDevelop.Ide.Commands; using MonoDevelop.Ide.Fonts; +using MonoDevelop.NUnit.External; namespace MonoDevelop.NUnit { @@ -370,13 +371,19 @@ namespace MonoDevelop.NUnit public void AddErrorMessage () { - string msg = GettextCatalog.GetString ("Internal error"); - if (errorMessage != null) - msg += ": " + Escape (errorMessage); + string msg; + if (error is RemoteUnhandledException) + msg = Escape (errorMessage); + else { + msg = GettextCatalog.GetString ("Internal error"); + if (errorMessage != null) + msg += ": " + Escape (errorMessage); + } var stock = ImageService.GetIcon (Ide.Gui.Stock.Error, Gtk.IconSize.Menu); TreeIter testRow = failuresStore.AppendValues (stock, msg, null, null, 0); - failuresStore.AppendValues (testRow, null, Escape (error.GetType ().Name + ": " + error.Message), null); + string name = error is RemoteUnhandledException ? ((RemoteUnhandledException)error).RemoteExceptionName : error.GetType ().Name; + failuresStore.AppendValues (testRow, null, Escape (name + ": " + error.Message), null); TreeIter row = failuresStore.AppendValues (testRow, null, GettextCatalog.GetString ("Stack Trace"), null, null, 0); AddStackTrace (row, error.StackTrace, null); } diff --git a/main/src/addins/NUnit/Services/ExternalTestRunner.cs b/main/src/addins/NUnit/Services/ExternalTestRunner.cs index 480c845aee..ea9f51d972 100644 --- a/main/src/addins/NUnit/Services/ExternalTestRunner.cs +++ b/main/src/addins/NUnit/Services/ExternalTestRunner.cs @@ -75,13 +75,24 @@ namespace MonoDevelop.NUnit.External Assembly.LoadFrom (asm); } - public UnitTestResult Run (IRemoteEventListener listener, ITestFilter filter, string path, string suiteName, List<string> supportAssemblies, string testRunnerType, string testRunnerAssembly) + public UnitTestResult Run (IRemoteEventListener listener, ITestFilter filter, string path, string suiteName, List<string> supportAssemblies, string testRunnerType, string testRunnerAssembly, string crashLogFile) { NUnitTestRunner runner = GetRunner (path); EventListenerWrapper listenerWrapper = listener != null ? new EventListenerWrapper (listener) : null; - TestResult res = runner.Run (listenerWrapper, filter, path, suiteName, supportAssemblies, testRunnerType, testRunnerAssembly); - return listenerWrapper.GetLocalTestResult (res); + UnhandledExceptionEventHandler exceptionHandler = (object sender, UnhandledExceptionEventArgs e) => { + + var ex = new RemoteUnhandledException ((Exception) e.ExceptionObject); + File.WriteAllText (crashLogFile, ex.Serialize ()); + }; + + AppDomain.CurrentDomain.UnhandledException += exceptionHandler; + try { + TestResult res = runner.Run (listenerWrapper, filter, path, suiteName, supportAssemblies, testRunnerType, testRunnerAssembly); + return listenerWrapper.GetLocalTestResult (res); + } finally { + AppDomain.CurrentDomain.UnhandledException -= exceptionHandler; + } } public NunitTestInfo GetTestInfo (string path, List<string> supportAssemblies) @@ -366,7 +377,47 @@ namespace MonoDevelop.NUnit.External { return null; } - } + + /// <summary> + /// Exception class that can be serialized + /// </summary> + class RemoteUnhandledException: Exception + { + string stack; + + public RemoteUnhandledException (string exceptionName, string message, string stack): base (message) + { + RemoteExceptionName = exceptionName; + this.stack = stack; + } + + public RemoteUnhandledException (Exception ex): base (ex.Message) + { + RemoteExceptionName = ex.GetType().Name; + this.stack = ex.StackTrace; + } + + public string Serialize () + { + return RemoteExceptionName + "\n" + Message.Replace ('\r',' ').Replace ('\n',' ') + "\n" + StackTrace; + } + + public static RemoteUnhandledException Parse (string s) + { + int i = s.IndexOf ('\n'); + string name = s.Substring (0, i++); + int i2 = s.IndexOf ('\n', i); + return new RemoteUnhandledException (name, s.Substring (i, i2 - i), s.Substring (i2 + 1)); + } + + public string RemoteExceptionName { get; set; } + + public override string StackTrace { + get { + return stack; + } + } + } } diff --git a/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs b/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs index 1fdde9f193..10a5467774 100644 --- a/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs +++ b/main/src/addins/NUnit/Services/NUnitAssemblyTestSuite.cs @@ -402,6 +402,7 @@ namespace MonoDevelop.NUnit testContext.Monitor.CancelRequested += new TestHandler (rd.Cancel); UnitTestResult result; + var crashLogFile = Path.GetTempFileName (); try { if (string.IsNullOrEmpty (AssemblyPath)) { @@ -413,11 +414,17 @@ namespace MonoDevelop.NUnit string testRunnerAssembly, testRunnerType; GetCustomTestRunner (out testRunnerAssembly, out testRunnerType); - result = runner.Run (localMonitor, filter, AssemblyPath, "", new List<string> (SupportAssemblies), testRunnerType, testRunnerAssembly); + result = runner.Run (localMonitor, filter, AssemblyPath, "", new List<string> (SupportAssemblies), testRunnerType, testRunnerAssembly, crashLogFile); if (testName != null) result = localMonitor.SingleTestResult; + + ReportCrash (testContext, crashLogFile); + } catch (Exception ex) { - if (!localMonitor.Canceled) { + if (ReportCrash (testContext, crashLogFile)) { + result = UnitTestResult.CreateFailure (GettextCatalog.GetString ("Undhandled exception"), null); + } + else if (!localMonitor.Canceled) { LoggingService.LogError (ex.ToString ()); if (localMonitor.RunningTest != null) { RuntimeErrorCleanup (testContext, localMonitor.RunningTest, ex); @@ -430,6 +437,7 @@ namespace MonoDevelop.NUnit result = UnitTestResult.CreateFailure (GettextCatalog.GetString ("Canceled"), null); } } finally { + File.Delete (crashLogFile); testContext.Monitor.CancelRequested -= new TestHandler (rd.Cancel); runner.Dispose (); System.Runtime.Remoting.RemotingServices.Disconnect (localMonitor); @@ -437,7 +445,18 @@ namespace MonoDevelop.NUnit return result; } - + + bool ReportCrash (TestContext testContext, string crashLogFile) + { + var crash = File.ReadAllText (crashLogFile); + if (crash.Length == 0) + return false; + + var ex = RemoteUnhandledException.Parse (crash); + testContext.Monitor.ReportRuntimeError (GettextCatalog.GetString ("Unhandled exception"), ex); + return true; + } + void RuntimeErrorCleanup (TestContext testContext, UnitTest t, Exception ex) { UnitTestResult result = UnitTestResult.CreateFailure (ex); diff --git a/main/src/addins/NUnit/templates/images/nunit-library-project.png b/main/src/addins/NUnit/templates/images/nunit-library-project.png Binary files differindex 20a93759c9..99f50eb029 100644 --- a/main/src/addins/NUnit/templates/images/nunit-library-project.png +++ b/main/src/addins/NUnit/templates/images/nunit-library-project.png diff --git a/main/src/addins/NUnit/templates/images/nunit-library-project@2x.png b/main/src/addins/NUnit/templates/images/nunit-library-project@2x.png Binary files differindex 4d0f78b9ec..86fcbe0866 100644 --- a/main/src/addins/NUnit/templates/images/nunit-library-project@2x.png +++ b/main/src/addins/NUnit/templates/images/nunit-library-project@2x.png diff --git a/main/src/addins/WindowsPlatform/WindowsPlatform/WindowsSecureStoragePasswordProvider.cs b/main/src/addins/WindowsPlatform/WindowsPlatform/WindowsSecureStoragePasswordProvider.cs index 413faaf567..ec2cf59f97 100644 --- a/main/src/addins/WindowsPlatform/WindowsPlatform/WindowsSecureStoragePasswordProvider.cs +++ b/main/src/addins/WindowsPlatform/WindowsPlatform/WindowsSecureStoragePasswordProvider.cs @@ -118,6 +118,38 @@ namespace MonoDevelop.Platform.Windows return Tuple.Create (string.Empty, string.Empty);
}
}
+
+ static bool RemoveCredential (string targetName)
+ {
+ if (targetName == null)
+ throw new ArgumentNullException ("targetName");
+
+ return NativeMethods.CredDelete (targetName, NativeCredentialType.Generic, 0);
+ }
+
+ public void RemoveWebPassword (Uri uri)
+ {
+ RemoveWebUserNameAndPassword (uri);
+ }
+
+ public void RemoveWebUserNameAndPassword (Uri uri)
+ {
+ var didDelete = RemoveCredential (uri.Host);
+ if (didDelete) return;
+
+ var lastError = (ErrorCode)Marshal.GetLastWin32Error ();
+ switch (lastError) {
+ case ErrorCode.NoSuchLogonSession:
+ LoggingService.LogError ("Tried saving credentials, but the logon session does not exist.");
+ break;
+ case ErrorCode.InvalidFlags:
+ LoggingService.LogError ("Tried saving credentials, but got invalid flags set on credential.");
+ break;
+ default:
+ LoggingService.LogError ("Tried saving credentials, but got unknown error code 0x{0:X}.", lastError);
+ break;
+ }
+ }
}
enum ErrorCode
@@ -263,5 +295,8 @@ namespace MonoDevelop.Platform.Windows [DllImport (ADVAPI32, CharSet = CharSet.Unicode, EntryPoint = "CredFree")]
internal static extern bool CredFree ([In] IntPtr cred);
+
+ [DllImport (ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CredDeleteW")]
+ internal static extern bool CredDelete (string targetName, NativeCredentialType type, CredentialFlags flags);
}
}
diff --git a/main/src/addins/Xml/Formatting/XmlFormatter.cs b/main/src/addins/Xml/Formatting/XmlFormatter.cs index 0db7df655f..705d7509c7 100644 --- a/main/src/addins/Xml/Formatting/XmlFormatter.cs +++ b/main/src/addins/Xml/Formatting/XmlFormatter.cs @@ -47,7 +47,7 @@ namespace MonoDevelop.Xml.Formatting } catch (Exception ex) { // Ignore malformed xml MonoDevelop.Core.LoggingService.LogWarning ("Error formatting XML file", ex); - return null; + return input; } var sw = new StringWriter (); diff --git a/main/src/core/Mono.Texteditor/Mono.TextEditor.Highlighting/ColorScheme.cs b/main/src/core/Mono.Texteditor/Mono.TextEditor.Highlighting/ColorScheme.cs index b2a0451ba3..c9f7798ae3 100644 --- a/main/src/core/Mono.Texteditor/Mono.TextEditor.Highlighting/ColorScheme.cs +++ b/main/src/core/Mono.Texteditor/Mono.TextEditor.Highlighting/ColorScheme.cs @@ -154,15 +154,24 @@ namespace Mono.TextEditor.Highlighting [ColorDescription("Column Ruler")] // not defined public AmbientColor Ruler { get; private set; } - [ColorDescription("Completion Matching Substring")] - public AmbientColor CompletionHighlight { get; private set; } + [ColorDescription("Completion Window")] + public AmbientColor CompletionWindow { get; private set; } - [ColorDescription("Completion Border")] - public AmbientColor CompletionBorder { get; private set; } + [ColorDescription("Completion Tooltip Window")] + public AmbientColor CompletionTooltipWindow { get; private set; } + + [ColorDescription("Completion Selection Bar Border")] + public AmbientColor CompletionSelectionBarBorder { get; private set; } + + [ColorDescription("Completion Selection Bar Border(Inactive)")] + public AmbientColor CompletionSelectionBarBorderInactive { get; private set; } + + [ColorDescription("Completion Selection Bar Background")] + public AmbientColor CompletionSelectionBarBackground { get; private set; } + + [ColorDescription("Completion Selection Bar Background(Inactive)")] + public AmbientColor CompletionSelectionBarBackgroundInactive { get; private set; } - [ColorDescription("Completion Border(Inactive)")] - public AmbientColor CompletionInactiveBorder { get; private set; } - [ColorDescription("Message Bubble Error Marker")] public AmbientColor MessageBubbleErrorMarker { get; private set; } @@ -324,10 +333,18 @@ namespace Mono.TextEditor.Highlighting [ColorDescription(CompletionTextKey)] //not defined in vs.net public ChunkStyle CompletionText { get; private set; } + public const string CompletionMatchingSubstringKey = "Completion Matching Substring"; + [ColorDescription(CompletionMatchingSubstringKey)] //not defined in vs.net + public ChunkStyle CompletionMatchingSubstring { get; private set; } + public const string CompletionSelectedTextKey = "Completion Selected Text"; [ColorDescription(CompletionSelectedTextKey)] //not defined in vs.net public ChunkStyle CompletionSelectedText { get; private set; } + public const string CompletionSelectedMatchingSubstringKey = "Completion Selected Matching Substring"; + [ColorDescription(CompletionSelectedMatchingSubstringKey)] //not defined in vs.net + public ChunkStyle CompletionSelectedMatchingSubstring { get; private set; } + public const string CompletionSelectedInactiveTextKey = "Completion Selected Text(Inactive)"; [ColorDescription(CompletionSelectedInactiveTextKey)] //not defined in vs.net public ChunkStyle CompletionSelectedInactiveText { get; private set; } diff --git a/main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditorData.cs b/main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditorData.cs index e18731ee32..10d9c02089 100644 --- a/main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditorData.cs +++ b/main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditorData.cs @@ -904,8 +904,6 @@ namespace Mono.TextEditor public void ClearSelection () { - if (!IsSomethingSelected) - return; MainSelection = Selection.Empty; } diff --git a/main/src/core/Mono.Texteditor/Styles/DefaultStyle.json b/main/src/core/Mono.Texteditor/Styles/DefaultStyle.json index d38ce55e4e..4fe514607e 100644 --- a/main/src/core/Mono.Texteditor/Styles/DefaultStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/DefaultStyle.json @@ -57,9 +57,12 @@ { "name":"Notification Border", "color":"#D2B457" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#666666" }, + { "name":"Completion Window", "color":"#edf1f2", "bordercolor":"#edf1f2" }, + { "name":"Completion Tooltip Window", "color":"#fafae2", "bordercolor":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#1379f1" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#a9a9a9" }, + { "name":"Completion Selection Bar Background", "color":"#1379f1", "secondcolor":"#1379f1" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"#a9a9a9", "secondcolor":"#a9a9a9" }, { "name":"Bookmarks", "color":"white", "secondcolor":"skyblue" }, @@ -155,9 +158,14 @@ { "name":"Tooltip Text", "fore":"text-black", "back":"#feffe9" }, { "name":"Notification Text", "fore":"text-black", "back":"#feffe9" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"#FFFFFF" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373", "weight":"bold" }, + + { "name":"Completion Selected Text", "fore":"#ffffff" }, + { "name":"Completion Selected Matching Substring", "fore":"#ffffff", "weight":"bold" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#ffffff" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#ffffff" }, { "name":"Keyword(Access)", "fore":"keyword-teal" }, { "name":"Keyword(Type)", "fore":"keyword-teal" }, diff --git a/main/src/core/Mono.Texteditor/Styles/MonokaiStyle.json b/main/src/core/Mono.Texteditor/Styles/MonokaiStyle.json index c56cbe1ba3..5e186c3625 100644 --- a/main/src/core/Mono.Texteditor/Styles/MonokaiStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/MonokaiStyle.json @@ -47,9 +47,12 @@ { "name":"Notification Border", "color":"#989892" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#bebebe" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"#FDD99B", "secondcolor":"#816647 " }, @@ -145,9 +148,14 @@ { "name":"Tooltip Text", "fore":"monokai-white", "back":"#272725" }, { "name":"Notification Text", "fore":"monokai-white", "back":"#272725" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"white", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"monokai-constant" }, { "name":"Keyword(Type)", "fore":"monokai-keyword" }, diff --git a/main/src/core/Mono.Texteditor/Styles/NightshadeStyle.json b/main/src/core/Mono.Texteditor/Styles/NightshadeStyle.json index 11aeb07916..294363d6e6 100644 --- a/main/src/core/Mono.Texteditor/Styles/NightshadeStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/NightshadeStyle.json @@ -83,9 +83,12 @@ { "name":"Notification Border", "color":"#989892" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#666666" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"aluminium1", "secondcolor":"aluminium4" }, @@ -181,9 +184,14 @@ { "name":"Tooltip Text", "fore":"NormalVim", "back":"#0a0a0a" }, { "name":"Notification Text", "fore":"NormalVim", "back":"#0a0a0a" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"TypeVim" }, { "name":"Keyword(Type)", "fore":"TypeVim" }, diff --git a/main/src/core/Mono.Texteditor/Styles/OblivionStyle.json b/main/src/core/Mono.Texteditor/Styles/OblivionStyle.json index e7064c653c..63820af424 100644 --- a/main/src/core/Mono.Texteditor/Styles/OblivionStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/OblivionStyle.json @@ -59,9 +59,12 @@ { "name":"Notification Border", "color":"aluminium1" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#bebebe" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"aluminium1", "secondcolor":"aluminium4" }, @@ -157,9 +160,14 @@ { "name":"Tooltip Text", "fore":"aluminium2", "back":"aluminium5" }, { "name":"Notification Text", "fore":"aluminium2", "back":"aluminium5" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"plum1", "weight":"bold" }, { "name":"Keyword(Type)", "fore":"plum1", "weight":"bold" }, diff --git a/main/src/core/Mono.Texteditor/Styles/SolarizedDarkStyle.json b/main/src/core/Mono.Texteditor/Styles/SolarizedDarkStyle.json index 920197e99f..6d39ba5f76 100644 --- a/main/src/core/Mono.Texteditor/Styles/SolarizedDarkStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/SolarizedDarkStyle.json @@ -48,9 +48,12 @@ { "name":"Notification Border", "color":"base1" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#bebebe" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"base3", "secondcolor":"blue" }, @@ -146,9 +149,14 @@ { "name":"Tooltip Text", "fore":"black", "back":"#feffe9" }, { "name":"Notification Text", "fore":"black", "back":"#feffe9" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"violet" }, { "name":"Keyword(Type)", "fore":"green" }, diff --git a/main/src/core/Mono.Texteditor/Styles/SolarizedLightStyle.json b/main/src/core/Mono.Texteditor/Styles/SolarizedLightStyle.json index 5ce265c4f1..e277467a0c 100644 --- a/main/src/core/Mono.Texteditor/Styles/SolarizedLightStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/SolarizedLightStyle.json @@ -48,9 +48,12 @@ { "name":"Notification Border", "color":"base1" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#bebebe" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"base3", "secondcolor":"blue" }, @@ -146,9 +149,14 @@ { "name":"Tooltip Text", "fore":"black", "back":"#feffe9" }, { "name":"Notification Text", "fore":"black", "back":"#feffe9" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"violet" }, { "name":"Keyword(Type)", "fore":"green" }, diff --git a/main/src/core/Mono.Texteditor/Styles/TangoStyle.json b/main/src/core/Mono.Texteditor/Styles/TangoStyle.json index 29fe565465..7b6b1fd964 100644 --- a/main/src/core/Mono.Texteditor/Styles/TangoStyle.json +++ b/main/src/core/Mono.Texteditor/Styles/TangoStyle.json @@ -59,9 +59,12 @@ { "name":"Notification Border", "color":"#b2b2b2" }, - { "name":"Completion Matching Substring", "color":"#BA3373" }, - { "name":"Completion Border", "color":"#C9C9C9" }, - { "name":"Completion Border(Inactive)", "color":"#666666" }, + { "name":"Completion Window", "color":"#F0F6F8" }, + { "name":"Completion Tooltip Window", "color":"#fafae2" }, + { "name":"Completion Selection Bar Border", "color":"#C9C9C9" }, + { "name":"Completion Selection Bar Border(Inactive)", "color":"#666666" }, + { "name":"Completion Selection Bar Background", "color":"#f8fcfc", "secondcolor":"#dff4f0" }, + { "name":"Completion Selection Bar Background(Inactive)", "color":"white", "secondcolor":"white" }, { "name":"Bookmarks", "color":"white", "secondcolor":"skyblue" }, @@ -157,9 +160,14 @@ { "name":"Tooltip Text", "fore":"black", "back":"#feffe9" }, { "name":"Notification Text", "fore":"black", "back":"#feffe9" }, - { "name":"Completion Text", "fore":"#434343", "back":"#F0F6F8" }, - { "name":"Completion Selected Text", "fore":"#f8fcfc", "back":"#dff4f0" }, - { "name":"Completion Selected Text(Inactive)", "fore":"#434343", "back":"white" }, + { "name":"Completion Text", "fore":"#434343" }, + { "name":"Completion Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring", "fore":"#BA3373" }, + + { "name":"Completion Selected Text(Inactive)", "fore":"#434343" }, + { "name":"Completion Selected Matching Substring(Inactive)", "fore":"#BA3373" }, { "name":"Keyword(Access)", "fore":"skyblue2" }, { "name":"Keyword(Type)", "fore":"skyblue2" }, diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Collections/ReadOnlyDictionary.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Collections/ReadOnlyDictionary.cs deleted file mode 100644 index d3143e8aac..0000000000 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Collections/ReadOnlyDictionary.cs +++ /dev/null @@ -1,130 +0,0 @@ -// ReadOnlyDictionary.cs -// -// Author: -// Lluis Sanchez Gual <lluis@novell.com> -// -// Copyright (c) 2008 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -// - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace MonoDevelop.Core.Collections -{ - public class ReadOnlyDictionary<TKey,TValue>: IDictionary<TKey,TValue>, IEnumerable - { - IDictionary<TKey,TValue> dictionary; - - public ReadOnlyDictionary (IDictionary<TKey,TValue> dictionary) - { - this.dictionary = dictionary; - } - - public TValue this [TKey key] { - get { - return dictionary [key]; - } - } - - public ICollection<TValue> Values { - get { return dictionary.Values; } - } - - public bool TryGetValue (TKey key, out TValue value) - { - return dictionary.TryGetValue (key, out value); - } - - public bool Contains (KeyValuePair<TKey, TValue> item) - { - return dictionary.Contains (item); - } - - public bool ContainsKey (TKey key) - { - return dictionary.ContainsKey (key); - } - - public void CopyTo (KeyValuePair<TKey, TValue>[] array, int arrayIndex) - { - dictionary.CopyTo (array, arrayIndex); - } - - public int Count { - get { return dictionary.Count; } - } - - public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator () - { - return dictionary.GetEnumerator (); - } - - public ICollection<TKey> Keys { - get { return dictionary.Keys; } - } - - bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly { - get { return true; } - } - - void ICollection<KeyValuePair<TKey, TValue>>.Add (KeyValuePair<TKey, TValue> item) - { - throw new NotSupportedException ("The dictionary is read-only."); - } - - void IDictionary<TKey,TValue>.Add (TKey key, TValue value) - { - throw new NotSupportedException ("The dictionary is read-only."); - } - - void ICollection<KeyValuePair<TKey, TValue>>.Clear () - { - throw new NotSupportedException ("The dictionary is read-only."); - } - bool ICollection<KeyValuePair<TKey, TValue>>.Remove (KeyValuePair<TKey, TValue> item) - { - throw new NotSupportedException ("The dictionary is read-only."); - } - - bool IDictionary<TKey,TValue>.Remove (TKey key) - { - throw new NotSupportedException ("The dictionary is read-only."); - } - - TValue IDictionary<TKey,TValue>.this [TKey key] { - get { - return dictionary [key]; - } - set { - throw new NotSupportedException ("The dictionary is read-only."); - } - } - - // IEnumerable - - IEnumerator IEnumerable.GetEnumerator () - { - return ((IEnumerable)dictionary).GetEnumerator (); - } - } -} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj index 615d9d8a87..cf9ebb887b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj @@ -195,7 +195,6 @@ <Compile Include="MonoDevelop.Core.Serialization\XmlElementDataType.cs" /> <Compile Include="MonoDevelop.Core.Serialization\XmlMapAttributeProvider.cs" /> <Compile Include="MonoDevelop.Core.Collections\Set.cs" /> - <Compile Include="MonoDevelop.Core.Collections\ReadOnlyDictionary.cs" /> <Compile Include="MonoDevelop.Core\Gettext.cs" /> <Compile Include="MonoDevelop.Core.AddIns\PackageInstalledCondition.cs" /> <Compile Include="MonoDevelop.Core\ComponentModelLocalization.cs" /> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/IPasswordProvider.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/IPasswordProvider.cs index 61647ef3ef..0601f58674 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/IPasswordProvider.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/IPasswordProvider.cs @@ -32,8 +32,11 @@ namespace MonoDevelop.Core { void AddWebPassword (Uri uri, string password); string GetWebPassword (Uri uri);
+ void RemoveWebPassword (Uri uri); + void AddWebUserNameAndPassword (Uri url, string username, string password);
- Tuple<string, string> GetWebUserNameAndPassword (Uri url);
+ Tuple<string, string> GetWebUserNameAndPassword (Uri url); + void RemoveWebUserNameAndPassword (Uri uri);
} } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/PasswordService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/PasswordService.cs index 94aca7c5e8..cc55f16ccf 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/PasswordService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/PasswordService.cs @@ -32,33 +32,51 @@ namespace MonoDevelop.Core { public static class PasswordService { - const string PasswordProvidersPath = "/MonoDevelop/Core/PasswordProvider"; + static IPasswordProvider GetPasswordProvider () + { + const string PasswordProvidersPath = "/MonoDevelop/Core/PasswordProvider"; + return AddinManager.GetExtensionObjects <IPasswordProvider> (PasswordProvidersPath).FirstOrDefault (); + } public static void AddWebPassword (Uri url, string password) { - var provider = AddinManager.GetExtensionObjects <IPasswordProvider> (PasswordProvidersPath).FirstOrDefault (); + var provider = GetPasswordProvider (); if (provider != null) provider.AddWebPassword (url, password); } public static void AddWebUserNameAndPassword (Uri url, string username, string password)
- {
- var provider = AddinManager.GetExtensionObjects<IPasswordProvider> (PasswordProvidersPath).FirstOrDefault ();
+ { + var provider = GetPasswordProvider (); if (provider != null)
provider.AddWebUserNameAndPassword (url, username, password);
}
public static string GetWebPassword (Uri url)
- {
- var provider = AddinManager.GetExtensionObjects<IPasswordProvider> (PasswordProvidersPath).FirstOrDefault ();
+ { + var provider = GetPasswordProvider (); return provider != null ? provider.GetWebPassword (url) : null;
}
public static Tuple<string, string> GetWebUserNameAndPassword (Uri url)
- {
- var provider = AddinManager.GetExtensionObjects<IPasswordProvider> (PasswordProvidersPath).FirstOrDefault ();
+ { + var provider = GetPasswordProvider (); return provider != null ? provider.GetWebUserNameAndPassword (url) : null;
} + + public static void RemoveWebPassword (Uri url) + { + var provider = GetPasswordProvider (); + if (provider != null) + provider.RemoveWebPassword (url); + } + + public static void RemoveWebUsernameAndPassword (Uri url) + { + var provider = GetPasswordProvider (); + if (provider != null) + provider.RemoveWebUserNameAndPassword (url); + } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/UnixSystemInformation.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/UnixSystemInformation.cs index 1f8f008731..e0b997e2f0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/UnixSystemInformation.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/UnixSystemInformation.cs @@ -27,7 +27,7 @@ using System; namespace MonoDevelop.Core { - public class UnixSystemInformation : SystemInformation + public abstract class UnixSystemInformation : SystemInformation { internal override void AppendOperatingSystem (System.Text.StringBuilder sb) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs index 68d1d3a1de..f1810f365a 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs @@ -847,7 +847,7 @@ namespace MonoDevelop.Projects var configs = GetConfigurations (configuration); string[] refs; - using (Counters.ResolveMSBuildReferencesTimer.BeginTiming (GetProjectEventMetadata ())) + using (Counters.ResolveMSBuildReferencesTimer.BeginTiming (GetProjectEventMetadata (configuration))) refs = builder.ResolveAssemblyReferences (configs, CancellationToken.None).Result; foreach (var r in refs) yield return r; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index e690901854..8bba03139a 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -331,7 +331,8 @@ namespace MonoDevelop.Projects protected override void OnEndLoad () { base.OnEndLoad (); - ProjectOpenedCounter.Inc (1, null, GetProjectEventMetadata ()); + + ProjectOpenedCounter.Inc (1, null, GetProjectEventMetadata (null)); } /// <summary> @@ -753,8 +754,8 @@ namespace MonoDevelop.Projects case "Clean": buildTimer = Counters.CleanMSBuildProjectTimer; break; } - var t1 = Counters.RunMSBuildTargetTimer.BeginTiming (GetProjectEventMetadata ()); - var t2 = buildTimer != null ? buildTimer.BeginTiming (GetProjectEventMetadata ()) : null; + var t1 = Counters.RunMSBuildTargetTimer.BeginTiming (GetProjectEventMetadata (configuration)); + var t2 = buildTimer != null ? buildTimer.BeginTiming (GetProjectEventMetadata (configuration)) : null; try { result = await builder.Run (configs, logWriter, MSBuildProjectService.DefaultMSBuildVerbosity, new[] { target }, null, null, monitor.CancellationToken); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs index 7c084a8477..a042646f4d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs @@ -568,7 +568,7 @@ namespace MonoDevelop.Projects string confName = iconf != null ? iconf.Id : solutionConfiguration.ToString (); monitor.BeginTask (GettextCatalog.GetString ("Building: {0} ({1})", Name, confName), 1); - using (Counters.BuildProjectTimer.BeginTiming ("Building " + Name, GetProjectEventMetadata ())) { + using (Counters.BuildProjectTimer.BeginTiming ("Building " + Name, GetProjectEventMetadata (solutionConfiguration))) { return await InternalBuild (monitor, solutionConfiguration); } @@ -577,7 +577,7 @@ namespace MonoDevelop.Projects } } - ITimeTracker tt = Counters.BuildProjectAndReferencesTimer.BeginTiming ("Building " + Name, GetProjectEventMetadata ()); + ITimeTracker tt = Counters.BuildProjectAndReferencesTimer.BeginTiming ("Building " + Name, GetProjectEventMetadata (solutionConfiguration)); try { // Get a list of all items that need to be built (including this), // and build them in the correct order @@ -695,7 +695,7 @@ namespace MonoDevelop.Projects async Task<BuildResult> CleanTask (ProgressMonitor monitor, ConfigurationSelector configuration) { - ITimeTracker tt = Counters.BuildProjectTimer.BeginTiming ("Cleaning " + Name, GetProjectEventMetadata ()); + ITimeTracker tt = Counters.BuildProjectTimer.BeginTiming ("Cleaning " + Name, GetProjectEventMetadata (configuration)); try { try { SolutionItemConfiguration iconf = GetConfiguration (configuration); @@ -803,9 +803,16 @@ namespace MonoDevelop.Projects inserted[index] = true; } - public IDictionary<string, string> GetProjectEventMetadata () + public IDictionary<string, string> GetProjectEventMetadata (ConfigurationSelector configurationSelector) { var data = new Dictionary<string, string> (); + if (configurationSelector != null) { + var slnConfig = configurationSelector as SolutionConfigurationSelector; + if (slnConfig != null) { + data ["Config.Id"] = slnConfig.Id; + } + } + OnGetProjectEventMetadata (data); return data; } diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml index f98ef0fbde..cc59fcf485 100644 --- a/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml +++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml @@ -481,9 +481,16 @@ <Command id = "MonoDevelop.Ide.Commands.FileCommands.OpenFolder" _label = "_Open Folder" _description = "Opens the folder in a file manager."/> - <Command id = "MonoDevelop.Ide.Commands.FileCommands.OpenContainingFolder" + <Condition id="Platform" value="!mac"> + <Command id = "MonoDevelop.Ide.Commands.FileCommands.OpenContainingFolder" _label = "O_pen Containing Folder" _description = "Opens the folder that contains this file."/> + </Condition> + <Condition id="Platform" value="mac"> + <Command id = "MonoDevelop.Ide.Commands.FileCommands.OpenContainingFolder" + _label = "Reveal in Finder" + _description = "Reveals the file in Finder."/> + </Condition> <Command id = "MonoDevelop.Ide.Commands.FileCommands.SetBuildAction" type="radio|array" _label = "Build action" /> diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/StockIcons.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/StockIcons.addin.xml index ec38d5a702..854507c358 100644 --- a/main/src/core/MonoDevelop.Ide/ExtensionModel/StockIcons.addin.xml +++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/StockIcons.addin.xml @@ -126,6 +126,7 @@ <StockIcon stockid="md-module" resource="element-module-16.png" size="Menu" /> <StockIcon stockid="md-name-space" resource="element-namespace-16.png" size="Menu" /> <StockIcon stockid="md-newmethod" resource="element-method-new-16.png" size="Menu" /> + <StockIcon stockid="md-nunit-overlay" resource="project-nunit-overlay-32.png" size="Dnd" /> <StockIcon stockid="md-other-declaration" resource="element-other-declaration-16.png" size="Menu" /> <StockIcon stockid="md-output-icon" resource="pad-application-output-16.png" size="Menu" /> <StockIcon stockid="md-package-source" resource="package-source-16.png" size="Menu" /> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs index 83dbce3a4b..cb8e5bd8a9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestClientSession.cs @@ -161,6 +161,11 @@ namespace MonoDevelop.Components.AutoTest return session.GetGlobalValue (name); } + public void TakeScreenshot (string screenshotPath) + { + session.TakeScreenshot (screenshotPath); + } + public T GetGlobalValue<T> (string name) { return (T) session.GetGlobalValue (name); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestSession.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestSession.cs index fb5fb14cdb..43a789c299 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestSession.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AutoTestSession.cs @@ -38,6 +38,12 @@ namespace MonoDevelop.Components.AutoTest { public class AutoTestSession: MarshalByRefObject { + [System.Runtime.InteropServices.DllImport ("/System/Library/Frameworks/QuartzCore.framework/QuartzCore")] + static extern IntPtr CGDisplayCreateImage (int displayID); + + [System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices", EntryPoint="CGMainDisplayID")] + internal static extern int MainDisplayID(); + readonly ManualResetEvent syncEvent = new ManualResetEvent (false); public readonly AutoTestSessionDebug SessionDebug = new AutoTestSessionDebug (); public IAutoTestSessionDebug<MarshalByRefObject> DebugObject { @@ -104,11 +110,14 @@ namespace MonoDevelop.Components.AutoTest public void ExitApp () { - try { - IdeApp.Exit (); - } catch (Exception e) { - Console.WriteLine (e); - } + Sync (delegate { + try { + IdeApp.Exit (); + } catch (Exception e) { + Console.WriteLine (e); + } + return true; + }); } public object GlobalInvoke (string name, object[] args) @@ -133,6 +142,24 @@ namespace MonoDevelop.Components.AutoTest return GetGlobalObject (name); }); } + + public void TakeScreenshot (string screenshotPath) + { + #if MAC + DispatchService.GuiDispatch (delegate { + try { + IntPtr handle = CGDisplayCreateImage (MainDisplayID ()); + CoreGraphics.CGImage screenshot = ObjCRuntime.Runtime.GetINativeObject <CoreGraphics.CGImage> (handle, true); + AppKit.NSBitmapImageRep imgRep = new AppKit.NSBitmapImageRep (screenshot); + var imageData = imgRep.RepresentationUsingTypeProperties (AppKit.NSBitmapImageFileType.Png); + imageData.Save (screenshotPath, true); + } catch (Exception e) { + Console.WriteLine (e); + throw; + } + }); + #endif + } public void SetGlobalValue (string name, object value) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuTreeView.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuTreeView.cs index c6ea099579..c1ec98b799 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuTreeView.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuTreeView.cs @@ -80,10 +80,10 @@ namespace MonoDevelop.Components } return base.OnButtonPressEvent (evnt); } - //pass click to base it it can update the selection - //unless the node is already selected, in which case we don't want to change the selection + //pass click to base so it can update the selection + //unless the node is already selected, in which case we don't want to change the selection(deselect multi selection) bool res = false; - if (!IsClickedNodeSelected ((int)evnt.X, (int)evnt.Y)) { + if (!this.IsClickedNodeSelected ((int)evnt.X, (int)evnt.Y)) { res = base.OnButtonPressEvent (evnt); } @@ -140,15 +140,6 @@ namespace MonoDevelop.Components return base.OnPopupMenu (); } - bool IsClickedNodeSelected (int x, int y) - { - Gtk.TreePath path; - if (GetPathAtPos (x, y, out path)) - return Selection.PathIsSelected (path); - - return false; - } - bool MultipleNodesSelected () { return Selection.GetSelectedRows ().Length > 1; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/GtkUtil.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/GtkUtil.cs index a083d352f2..6704049b7e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/GtkUtil.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/GtkUtil.cs @@ -180,6 +180,15 @@ namespace MonoDevelop.Components return new Gdk.Point (x + p.X, y + p.Y); } + public static bool IsClickedNodeSelected (this Gtk.TreeView tree, int x, int y) + { + Gtk.TreePath path; + if (tree.GetPathAtPos (x, y, out path)) + return tree.Selection.PathIsSelected (path); + + return false; + } + public static void EnableAutoTooltips (this Gtk.TreeView tree) { TreeViewTooltipsData data = new TreeViewTooltipsData (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs index 32dce6f16d..8667066415 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs @@ -594,6 +594,10 @@ namespace MonoDevelop.Ide.CodeCompletion } else { declarationviewwindow.SetDefaultScheme (); } + var style = Editor.Highlighting.SyntaxModeService.GetColorStyle (IdeApp.Preferences.ColorScheme); + declarationviewwindow.Theme.SetFlatColor (style.CompletionTooltipWindow.Color); + if (style.CompletionWindow.HasBorderColor) + declarationviewwindow.Theme.BorderColor = style.CompletionTooltipWindow.BorderColor; } void RepositionDeclarationViewWindow () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs index 5677261a1c..6b56320cc9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs @@ -39,6 +39,8 @@ using System.ComponentModel.Design; using MonoDevelop.Ide.Editor.Highlighting; using MonoDevelop.Ide.Editor.Extension; using MonoDevelop.Core; +using Xwt.Drawing; +using MonoDevelop.Ide.TypeSystem; namespace MonoDevelop.Ide.CodeCompletion { @@ -125,11 +127,6 @@ namespace MonoDevelop.Ide.CodeCompletion } } - Cairo.Color backgroundColor; - Cairo.Color selectionBorderColor, selectionBorderInactiveColor; - ChunkStyle selectedItemColor, selectedItemInactiveColor; - Cairo.Color textColor; - Cairo.Color highlightColor; FontDescription itemFont; const int marginIconSpacing = 4; @@ -143,7 +140,7 @@ namespace MonoDevelop.Ide.CodeCompletion if (itemFont != null) itemFont.Dispose (); itemFont = FontService.MonospaceFont.Copy (); - var newSize = (itemFont.Size * (completionWidget != null ? this.completionWidget.ZoomLevel : 1)); + var newSize = (itemFont.Size - 1 * Pango.Scale.PangoScale) * (completionWidget != null ? this.completionWidget.ZoomLevel : 1); if (newSize > 0) { itemFont.Size = (int)newSize; layout.FontDescription = itemFont; @@ -159,16 +156,8 @@ namespace MonoDevelop.Ide.CodeCompletion noMatchLayout = new Pango.Layout (this.PangoContext); layout = new Pango.Layout (this.PangoContext); layout.Wrap = Pango.WrapMode.Char; - var style = SyntaxModeService.GetColorStyle (IdeApp.Preferences.ColorScheme); + SetFont (); - textColor = style.CompletionText.Foreground; - - highlightColor = style.CompletionHighlight.Color; - backgroundColor = style.CompletionText.Background; - selectedItemColor = style.CompletionSelectedText; - selectedItemInactiveColor = style.CompletionSelectedInactiveText; - selectionBorderColor = style.CompletionBorder.Color; - selectionBorderInactiveColor = style.CompletionInactiveBorder.Color; this.Show (); } @@ -435,12 +424,12 @@ namespace MonoDevelop.Ide.CodeCompletion int width = alloc.Width; int height = alloc.Height; context.Rectangle (args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height); + var backgroundColor = ColorScheme.CompletionWindow.Color; + var textColor = ColorScheme.CompletionText.Foreground; context.SetSourceColor (backgroundColor); context.Fill (); - int xpos = iconTextSpacing; int yPos = (int)-vadj.Value; - //when there are no matches, display a message to indicate that the completion list is still handling input if (filteredItems.Count == 0) { context.Rectangle (0, yPos, width, height - yPos); @@ -471,12 +460,12 @@ namespace MonoDevelop.Ide.CodeCompletion } context.Rectangle (0, ypos, Allocation.Width, rowHeight); context.SetSourceColor (backgroundColor); - context.Fill (); - - -// layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); -// window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout); -// layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); + context.Fill ();
+
+
+ // layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); + // window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout); + // layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>"); categoryLayout.SetMarkup ((category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized")); int px, py; categoryLayout.GetPixelSize (out px, out py); @@ -502,30 +491,44 @@ namespace MonoDevelop.Ide.CodeCompletion } else { layout.SetMarkup (markup + " " + description); } - + string text = win.DataProvider.GetText (item); - + if (!string.IsNullOrEmpty (text)) { - int[] matchIndices = matcher.GetMatch (text); + int [] matchIndices = matcher.GetMatch (text); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { int idx = matchIndices [newSelection]; - var fg = new AttrForeground ((ushort)(highlightColor.R * ushort.MaxValue), (ushort)(highlightColor.G * ushort.MaxValue), (ushort)(highlightColor.B * ushort.MaxValue)); + ChunkStyle stringStyle; + if (item == SelectedItem) { + stringStyle = ColorScheme.CompletionSelectedMatchingSubstring; + } else { + stringStyle= ColorScheme.CompletionMatchingSubstring; + } + var highlightColor = (Cairo.Color)stringStyle.Foreground; + var fg = new AttrForeground ((ushort)(highlightColor.R * ushort.MaxValue), (ushort)(highlightColor.G * ushort.MaxValue), (ushort)(highlightColor.B * ushort.MaxValue)); fg.StartIndex = (uint)idx; fg.EndIndex = (uint)(idx + 1); attrList.Insert (fg); + + if (stringStyle.FontWeight != FontWeight.Normal) { + var variant = new AttrWeight ((Pango.Weight)stringStyle.FontWeight); + variant.StartIndex = (uint)idx; + variant.EndIndex = (uint)(idx + 1); + attrList.Insert (variant); + } } layout.Attributes = attrList; } } - + Xwt.Drawing.Image icon = win.DataProvider.GetIcon (item); int iconHeight, iconWidth; if (icon != null) { iconWidth = (int)icon.Width; iconHeight = (int)icon.Height; - } else if (!Gtk.Icon.SizeLookup (Gtk.IconSize.Menu, out iconWidth, out iconHeight)) { + } else if (!Gtk.Icon.SizeLookup (IconSize.Menu, out iconWidth, out iconHeight)) { iconHeight = iconWidth = 24; } @@ -533,20 +536,23 @@ namespace MonoDevelop.Ide.CodeCompletion layout.GetPixelSize (out wi, out he); - typos = he < rowHeight ? ypos + (rowHeight - he) / 2 : ypos; + typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos; iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos; if (item == SelectedItem) { context.Rectangle (0, ypos, Allocation.Width, rowHeight / 2); - context.SetSourceColor (SelectionEnabled ? selectedItemColor.Foreground : selectedItemInactiveColor.Background); + var barStyle = SelectionEnabled ? ColorScheme.CompletionSelectionBarBackground : ColorScheme.CompletionSelectionBarBackgroundInactive; + var barBorderStyle = SelectionEnabled ? ColorScheme.CompletionSelectionBarBorder : ColorScheme.CompletionSelectionBarBorderInactive; + + context.SetSourceColor (barStyle.Color); context.Fill (); context.Rectangle (0, ypos + rowHeight / 2, Allocation.Width, rowHeight / 2); - context.SetSourceColor (SelectionEnabled ? selectedItemColor.Background : selectedItemInactiveColor.Background); + context.SetSourceColor (barStyle.SecondColor); context.Fill (); context.Rectangle (0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1); if (!SelectionEnabled) context.SetDash (new double[] {4, 4}, 0); - context.SetSourceColor (SelectionEnabled ? selectionBorderColor : selectionBorderInactiveColor); + context.SetSourceColor (barBorderStyle.Color); context.Stroke (); } @@ -554,7 +560,7 @@ namespace MonoDevelop.Ide.CodeCompletion context.DrawImage (this, icon, xpos, iypos); xpos += iconTextSpacing; } - context.SetSourceColor (textColor); + context.SetSourceColor (item == SelectedItem ? ColorScheme.CompletionSelectedText.Foreground : textColor); var textXPos = xpos + iconWidth + 2; context.MoveTo (textXPos, typos); layout.Width = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale); @@ -741,11 +747,8 @@ namespace MonoDevelop.Ide.CodeCompletion void CalcVisibleRows () { - - int rowWidth; - layout.SetText ("F_B"); - layout.GetPixelSize (out rowWidth, out rowHeight); - rowHeight = Math.Max (1, rowHeight * 3 / 2); + var icon = ImageService.GetIcon (TypeSystem.Stock.Namespace, IconSize.Menu); + rowHeight = Math.Max (1, (int)icon.Height + 2); int newHeight = rowHeight * IdeApp.Preferences.CompletionListRows; if (Allocation.Width != listWidth || Allocation.Height != newHeight) @@ -754,7 +757,8 @@ namespace MonoDevelop.Ide.CodeCompletion } const int spacing = 2; - + ColorScheme ColorScheme => SyntaxModeService.GetColorStyle (IdeApp.Preferences.ColorScheme); + delegate void CategoryAction (Category category, int yPos); delegate bool ItemAction (Category curCategory, int item, int itemIndex, int yPos); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs index 616d0cdd83..fd30f7ea94 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs @@ -100,8 +100,15 @@ namespace MonoDevelop.Ide.CodeCompletion this.AutoSelect = true; this.TypeHint = WindowTypeHint.Menu; Theme.CornerRadius = 4; + } + + protected override void OnShown () + { var style = SyntaxModeService.GetColorStyle (IdeApp.Preferences.ColorScheme); - Theme.SetFlatColor (style.CompletionText.Background); + Theme.SetFlatColor (style.CompletionWindow.Color); + if (style.CompletionWindow.HasBorderColor) + Theme.BorderColor = style.CompletionWindow.BorderColor; + base.OnShown (); } protected virtual void DoubleClick () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/TooltipInformationWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/TooltipInformationWindow.cs index 528bb4a685..506e6dfaf0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/TooltipInformationWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/TooltipInformationWindow.cs @@ -126,7 +126,9 @@ namespace MonoDevelop.Ide.CodeCompletion } if (!string.IsNullOrEmpty (o.SummaryMarkup)) { - descriptionBox.PackStart (CreateCategory (GettextCatalog.GetString ("Summary"), o.SummaryMarkup), true, true, 4); + descriptionBox.PackStart (CreateCategory ( + "<span foreground=\"#a7a79c\" size=\"larger\">" + + GettextCatalog.GetString ("Summary") +"</span>", o.SummaryMarkup, true), true, true, 4); } if (!string.IsNullOrEmpty (o.FooterMarkup)) { @@ -192,21 +194,27 @@ namespace MonoDevelop.Ide.CodeCompletion current_overload = 0; } - VBox CreateCategory (string categoryName, string categoryContentMarkup) + VBox CreateCategory (string categoryName, string categoryContentMarkup, bool useParagraphForContent = false) { var vbox = new VBox (); - vbox.Spacing = 2; + vbox.Spacing = 8; if (categoryName != null) { var catLabel = new FixedWidthWrapLabel (); - catLabel.Text = categoryName; + catLabel.Markup = categoryName; catLabel.ModifyFg (StateType.Normal, foreColor.ToGdkColor ()); catLabel.FontDescription = FontService.GetFontDescription ("Editor"); vbox.PackStart (catLabel, false, true, 0); } var contentLabel = new FixedWidthWrapLabel (); + HBox hbox = new HBox (); + + if (useParagraphForContent) { + hbox.PackStart (new Label(), false, true, 10); + } + contentLabel.Wrap = Pango.WrapMode.WordChar; contentLabel.BreakOnCamelCasing = false; contentLabel.BreakOnPunctuation = false; @@ -215,7 +223,8 @@ namespace MonoDevelop.Ide.CodeCompletion contentLabel.ModifyFg (StateType.Normal, foreColor.ToGdkColor ()); contentLabel.FontDescription = FontService.GetFontDescription ("Editor"); - vbox.PackStart (contentLabel, true, true, 0); + hbox.PackStart (contentLabel, true, true, 0); + vbox.PackStart (hbox, true, true, 0); return vbox; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ColorScheme.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ColorScheme.cs index 09e5d84779..b558da920e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ColorScheme.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ColorScheme.cs @@ -154,14 +154,23 @@ namespace MonoDevelop.Ide.Editor.Highlighting [ColorDescription("Column Ruler")] // not defined public AmbientColor Ruler { get; private set; } - [ColorDescription("Completion Matching Substring")] - public AmbientColor CompletionHighlight { get; private set; } + [ColorDescription("Completion Selection Bar Border")] + public AmbientColor CompletionSelectionBarBorder { get; private set; } - [ColorDescription("Completion Border")] - public AmbientColor CompletionBorder { get; private set; } + [ColorDescription("Completion Window")] + public AmbientColor CompletionWindow { get; private set; } - [ColorDescription("Completion Border(Inactive)")] - public AmbientColor CompletionInactiveBorder { get; private set; } + [ColorDescription("Completion Tooltip Window")] + public AmbientColor CompletionTooltipWindow { get; private set; } + + [ColorDescription("Completion Selection Bar Border(Inactive)")] + public AmbientColor CompletionSelectionBarBorderInactive { get; private set; } + + [ColorDescription("Completion Selection Bar Background")] + public AmbientColor CompletionSelectionBarBackground { get; private set; } + + [ColorDescription("Completion Selection Bar Background(Inactive)")] + public AmbientColor CompletionSelectionBarBackgroundInactive { get; private set; } [ColorDescription("Message Bubble Error Marker")] public AmbientColor MessageBubbleErrorMarker { get; private set; } @@ -324,14 +333,26 @@ namespace MonoDevelop.Ide.Editor.Highlighting [ColorDescription(CompletionTextKey)] //not defined in vs.net public ChunkStyle CompletionText { get; private set; } + public const string CompletionMatchingSubstringKey = "Completion Matching Substring"; + [ColorDescription(CompletionMatchingSubstringKey)] //not defined in vs.net + public ChunkStyle CompletionMatchingSubstring { get; private set; } + public const string CompletionSelectedTextKey = "Completion Selected Text"; [ColorDescription(CompletionSelectedTextKey)] //not defined in vs.net public ChunkStyle CompletionSelectedText { get; private set; } + public const string CompletionSelectedMatchingSubstringKey = "Completion Selected Matching Substring"; + [ColorDescription(CompletionSelectedMatchingSubstringKey)] //not defined in vs.net + public ChunkStyle CompletionSelectedMatchingSubstring { get; private set; } + public const string CompletionSelectedInactiveTextKey = "Completion Selected Text(Inactive)"; [ColorDescription(CompletionSelectedInactiveTextKey)] //not defined in vs.net public ChunkStyle CompletionSelectedInactiveText { get; private set; } + public const string CompletionSelectedInactiveMatchingSubstringKey = "Completion Selected Matching Substring(Inactive)"; + [ColorDescription(CompletionSelectedInactiveMatchingSubstringKey)] //not defined in vs.net + public ChunkStyle CompletionSelectedInactiveMatchingSubstring { get; private set; } + public const string KeywordAccessorsKey = "Keyword(Access)"; [ColorDescription(KeywordAccessorsKey, VSSetting = "Keyword")] public ChunkStyle KeywordAccessors { get; private set; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs index 2f37ec6a29..4a36ca86d0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditorViewContent.cs @@ -697,12 +697,19 @@ namespace MonoDevelop.Ide.Editor static IEnumerable<IDocumentLine> GetSelectedLines (TextEditor textEditor) { - var selection = textEditor.SelectionRange; - var line = textEditor.GetLineByOffset (selection.EndOffset); - do { + if (!textEditor.IsSomethingSelected) { + yield return textEditor.GetLine (textEditor.CaretLine); + yield break; + } + var selection = textEditor.SelectionRegion; + var line = textEditor.GetLine(selection.EndLine); + if (selection.EndColumn == 1 && textEditor.SelectionLeadOffset < textEditor.SelectionAnchorOffset) + line = line.PreviousLine; + + while (line != null && line.LineNumber >= selection.BeginLine) { yield return line; line = line.PreviousLine; - } while (line != null && line.EndOffset > selection.Offset); + } } [CommandHandler (EditCommands.AddCodeComment)] diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs index e6a36f1d25..1201c9110c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs @@ -39,6 +39,7 @@ namespace MonoDevelop.Ide.FindInFiles { public enum PathMode { Absolute, + Relative, Hidden } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs index 85d7601f9b..43015005c1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs @@ -34,7 +34,6 @@ namespace MonoDevelop.Ide.FindInFiles { public interface ISearchProgressMonitor { - void SetBasePath (string path); void ReportResult (SearchResult result); void ReportResults (IEnumerable<SearchResult> result); void ReportStatus (string resultMessage); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs index 2ddc9dd417..f8a6fc139f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs @@ -45,7 +45,15 @@ namespace MonoDevelop.Ide.FindInFiles } public virtual PathMode PathMode { - get { return PathMode.Absolute; } + get { + var workspace = IdeApp.Workspace; + var solutions = workspace != null ? workspace.GetAllSolutions () : null; + + if (solutions != null && solutions.Count () == 1) + return PathMode.Relative; + + return PathMode.Absolute; + } } public abstract int GetTotalWork (FilterOptions filterOptions); @@ -228,6 +236,10 @@ namespace MonoDevelop.Ide.FindInFiles readonly string path; readonly bool recurse; + public override PathMode PathMode { + get { return PathMode.Absolute; } + } + public bool IncludeHiddenFiles { get; set; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs index aeed4d6e8d..472e17bdf0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs @@ -47,11 +47,6 @@ namespace MonoDevelop.Ide.FindInFiles outputPad.CancellationTokenSource = CancellationTokenSource; outputPad.BeginProgress (pad.Title); } - - public void SetBasePath (string path) - { - outputPad.BasePath = path; - } public PathMode PathMode { set { outputPad.PathMode = value; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs index ad0acbb87e..57ad2848d0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs @@ -73,15 +73,6 @@ namespace MonoDevelop.Ide.FindInFiles return widget.AllowReuse; } } - - public string BasePath { - get { - return widget.BasePath; - } - set { - widget.BasePath = value; - } - } internal PathMode PathMode { set { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs index e32206e69c..f9a68c9c35 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs @@ -67,18 +67,16 @@ namespace MonoDevelop.Ide.FindInFiles TextView textviewLog; TreeViewColumn pathColumn; - public string BasePath { - get; - set; - } - public CancellationTokenSource CancellationTokenSource { get; set; } + private PathMode pathMode; internal PathMode PathMode { set { + pathMode = value; + pathColumn.Visible = (value != PathMode.Hidden); } } @@ -472,7 +470,19 @@ namespace MonoDevelop.Ide.FindInFiles string pathMarkup = searchResult.PathMarkup; if (pathMarkup == null) { bool didRead = (bool)store.GetValue (iter, DidReadColumn); - pathMarkup = MarkupText (System.IO.Path.GetDirectoryName (searchResult.FileName), didRead); + + var fileName = searchResult.FileName; + string baseSolutionPath = null; + if (pathMode == PathMode.Relative) { + var workspace = IdeApp.Workspace; + var solutions = workspace != null ? workspace.GetAllSolutions () : null; + baseSolutionPath = solutions != null && solutions.Count () == 1 ? solutions.First ().BaseDirectory : null; + } + var finalFileName = baseSolutionPath == null ? fileName : + FileService.AbsoluteToRelativePath (baseSolutionPath, fileName); + var directory = System.IO.Path.GetDirectoryName (finalFileName); + + pathMarkup = MarkupText (directory, didRead); searchResult.PathMarkup = pathMarkup; } pathRenderer.Markup = pathMarkup; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs index 0b08c7501a..58e76f61b3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs @@ -307,10 +307,14 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad } var removeFromProject = new AlertButton (GettextCatalog.GetString ("_Remove from Project"), Gtk.Stock.Remove); - string question, secondaryText; - - secondaryText = GettextCatalog.GetString ("The Delete option permanently removes the file from your hard disk. " + - "Click Remove from Project if you only want to remove it from your current solution."); + string question; + string secondaryText = null; + + bool filesExist = CheckAnyFileExists (files); + if (filesExist) { + secondaryText = GettextCatalog.GetString ("The Delete option permanently removes the file from your hard disk. " + + "Click Remove from Project if you only want to remove it from your current solution."); + } if (hasChildren) { if (files.Count == 1) @@ -328,7 +332,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad question = GettextCatalog.GetString ("Are you sure you want to remove the selected files from the project?"); } - var result = MessageService.AskQuestion (question, secondaryText, AlertButton.Delete, AlertButton.Cancel, removeFromProject); + var result = MessageService.AskQuestion (question, secondaryText, GetDeleteConfirmationButtons (filesExist, removeFromProject)); if (result != removeFromProject && result != AlertButton.Delete) return; @@ -359,6 +363,29 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad IdeApp.ProjectOperations.SaveAsync (projects); } + + static bool CheckAnyFileExists (IEnumerable<ProjectFile> files) + { + foreach (ProjectFile file in files) { + if (!file.IsLink && File.Exists (file.Name)) + return true; + + if (file.HasChildren) { + foreach (var child in file.DependentChildren.ToArray()) { + if (File.Exists (child.Name)) + return true; + } + } + } + return false; + } + + static AlertButton[] GetDeleteConfirmationButtons (bool includeDelete, AlertButton removeFromProject) + { + if (includeDelete) + return new [] { AlertButton.Delete, AlertButton.Cancel, removeFromProject }; + return new [] { AlertButton.Cancel, removeFromProject }; + } [CommandUpdateHandler (EditCommands.Delete)] public void UpdateRemoveItem (CommandInfo info) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs index 119b22075b..8719b1c5f4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs @@ -841,7 +841,7 @@ namespace MonoDevelop.Ide.Gui CancelOldParsing (); var token = parseTokenSource.Token; var project = Project ?? adhocProject; - var projectFile = project.GetProjectFile (currentParseFile); + var projectFile = project?.GetProjectFile (currentParseFile); ThreadPool.QueueUserWorkItem (delegate { TypeSystemService.AddSkippedFile (currentParseFile); if (project != null && TypeSystemService.CanParseProjections (project, mimeType, currentParseFile)) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizard.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizard.cs index 13ece7e1ee..768a740758 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizard.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizard.cs @@ -60,7 +60,14 @@ namespace MonoDevelop.Ide.Templates List<string> supportedParameters; - internal void UpdateSupportedParameters (string parameters) + internal void UpdateParameters (SolutionTemplate template) + { + Parameters ["TemplateName"] = template.Name; + UpdateSupportedParameters (template.SupportedParameters); + UpdateDefaultParameters (template.DefaultParameters); + } + + void UpdateSupportedParameters (string parameters) { if (String.IsNullOrEmpty (parameters)) { supportedParameters = null; @@ -82,7 +89,7 @@ namespace MonoDevelop.Ide.Templates return supportedParameters.Contains (name); } - internal void UpdateDefaultParameters (string parameters) + void UpdateDefaultParameters (string parameters) { if (String.IsNullOrEmpty (parameters)) { return; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizardProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizardProvider.cs index acd12b7278..f492ec48ed 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizardProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateWizardProvider.cs @@ -93,8 +93,7 @@ namespace MonoDevelop.Ide.Templates }
CurrentWizard.Parameters = parameters;
- CurrentWizard.UpdateSupportedParameters (template.SupportedParameters);
- CurrentWizard.UpdateDefaultParameters (template.DefaultParameters);
+ CurrentWizard.UpdateParameters (template);
IsFirstPage = true;
CurrentPageNumber = 1;
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs index 575153a2e2..41af6f412e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs @@ -402,6 +402,8 @@ namespace MonoDevelop.Ide.TypeSystem foreach (var f in p.Files) { if (token.IsCancellationRequested) yield break; + if (f.Subtype == MonoDevelop.Projects.Subtype.Directory) + continue; if (TypeSystemParserNode.IsCompileBuildAction (f.BuildAction)) { if (!duplicates.Add (projectData.GetOrCreateDocumentId (f.Name))) continue; @@ -691,7 +693,6 @@ namespace MonoDevelop.Ide.TypeSystem { var id = info.Id; var path = DetermineFilePath (info.Id, info.Name, info.FilePath, info.Folders, true); - MonoDevelop.Projects.Project mdProject = null; if (id.ProjectId != null) { @@ -822,10 +823,13 @@ namespace MonoDevelop.Ide.TypeSystem return; var project = (MonoDevelop.Projects.Project)sender; foreach (MonoDevelop.Projects.ProjectFileEventInfo fargs in args) { - if (!TypeSystemParserNode.IsCompileBuildAction (fargs.ProjectFile.BuildAction)) + var projectFile = fargs.ProjectFile; + if (projectFile.Subtype == MonoDevelop.Projects.Subtype.Directory) + continue; + if (!TypeSystemParserNode.IsCompileBuildAction (projectFile.BuildAction)) continue; var projectId = GetProjectId (project); - var newDocument = CreateDocumentInfo (project.Name, GetProjectData (projectId), fargs.ProjectFile); + var newDocument = CreateDocumentInfo(project.Name, GetProjectData(projectId), projectFile); OnDocumentAdded (newDocument); } } @@ -853,7 +857,10 @@ namespace MonoDevelop.Ide.TypeSystem return; var project = (MonoDevelop.Projects.Project)sender; foreach (MonoDevelop.Projects.ProjectFileRenamedEventInfo fargs in args) { - if (!TypeSystemParserNode.IsCompileBuildAction (fargs.ProjectFile.BuildAction)) + var projectFile = fargs.ProjectFile; + if (projectFile.Subtype == MonoDevelop.Projects.Subtype.Directory) + continue; + if (!TypeSystemParserNode.IsCompileBuildAction (projectFile.BuildAction)) continue; var projectId = GetProjectId (project); @@ -868,7 +875,7 @@ namespace MonoDevelop.Ide.TypeSystem data.RemoveDocument (fargs.OldName); } - var newDocument = CreateDocumentInfo (project.Name, GetProjectData (projectId), fargs.ProjectFile); + var newDocument = CreateDocumentInfo (project.Name, GetProjectData (projectId), projectFile); OnDocumentAdded (newDocument); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index e820f31e34..3b4bd434e6 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -1955,6 +1955,12 @@ <EmbeddedResource Include="icons\done-48%402x.png"> <LogicalName>done-48@2x.png</LogicalName> </EmbeddedResource> + <EmbeddedResource Include="icons\project-nunit-overlay-32.png"> + <LogicalName>project-nunit-overlay-32.png</LogicalName> + </EmbeddedResource> + <EmbeddedResource Include="icons\project-nunit-overlay-32%402x.png"> + <LogicalName>project-nunit-overlay-32@2x.png</LogicalName> + </EmbeddedResource> </ItemGroup> <ItemGroup Condition=" '$(Configuration)' != 'DebugMac' AND '$(Configuration)' != 'ReleaseMac' "> <EmbeddedResource Include="icons\status-building-1-14.png"> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/HelpOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/HelpOperations.cs index df86d6de4c..5fa09264e4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/HelpOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/HelpOperations.cs @@ -59,6 +59,7 @@ namespace MonoDevelop.Ide AddDirArgs (builder); builder.AddQuoted (extraArgs); } else { + LoggingService.LogWarning ("MonoDoc.app folder not found at {0}.", mdapp); builder.AddQuoted (url); builder.AddQuoted (extraArgs); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs index 0f7395e565..09eada62f0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs @@ -141,7 +141,7 @@ namespace MonoDevelop.Ide public readonly ConfigurationProperty<bool> AddOpeningOnly = ConfigurationProperty.Create ("AddOpeningOnly", false); public readonly ConfigurationProperty<bool> FilterCompletionListByEditorBrowsable = ConfigurationProperty.Create ("FilterCompletionListByEditorBrowsable", true); public readonly ConfigurationProperty<bool> IncludeEditorBrowsableAdvancedMembers = ConfigurationProperty.Create ("IncludeEditorBrowsableAdvancedMembers", true); - public readonly ConfigurationProperty<int> CompletionListRows = ConfigurationProperty.Create ("CompletionListRows", 7); + public readonly ConfigurationProperty<int> CompletionListRows = ConfigurationProperty.Create ("CompletionListRows", 10); public readonly ConfigurationProperty<bool> EnableSourceAnalysis = ConfigurationProperty.Create ("MonoDevelop.AnalysisCore.AnalysisEnabled", false); public readonly ConfigurationProperty<bool> EnableUnitTestEditorIntegration = ConfigurationProperty.Create ("Testing.EnableUnitTestEditorIntegration", false); diff --git a/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32.png b/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32.png Binary files differnew file mode 100644 index 0000000000..daa6d0d2a5 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32.png diff --git a/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32@2x.png b/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32@2x.png Binary files differnew file mode 100644 index 0000000000..664f413a7a --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/icons/project-nunit-overlay-32@2x.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/console-project.png b/main/src/core/MonoDevelop.Ide/templates/images/console-project.png Binary files differindex 989d9a7312..cf1766ba08 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/console-project.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/console-project.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/console-project@2x.png b/main/src/core/MonoDevelop.Ide/templates/images/console-project@2x.png Binary files differindex 14ce6f4b0c..f92dae0e23 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/console-project@2x.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/console-project@2x.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project.png b/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project.png Binary files differindex 235de431e2..b0dde6991b 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project@2x.png b/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project@2x.png Binary files differindex f810211460..e29687e63d 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project@2x.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/gtk2-project@2x.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/library-project.png b/main/src/core/MonoDevelop.Ide/templates/images/library-project.png Binary files differindex 8afc910299..f6210a7daa 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/library-project.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/library-project.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/library-project@2x.png b/main/src/core/MonoDevelop.Ide/templates/images/library-project@2x.png Binary files differindex 8975e1bfc9..b9c35577c2 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/library-project@2x.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/library-project@2x.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/pcl-project.png b/main/src/core/MonoDevelop.Ide/templates/images/pcl-project.png Binary files differindex 9367ca0068..81e7cd51fc 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/pcl-project.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/pcl-project.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/pcl-project@2x.png b/main/src/core/MonoDevelop.Ide/templates/images/pcl-project@2x.png Binary files differindex fc5354f27e..f23c248330 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/pcl-project@2x.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/pcl-project@2x.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/shared-project.png b/main/src/core/MonoDevelop.Ide/templates/images/shared-project.png Binary files differindex 7d0c114ee2..1b55f0a651 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/shared-project.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/shared-project.png diff --git a/main/src/core/MonoDevelop.Ide/templates/images/shared-project@2x.png b/main/src/core/MonoDevelop.Ide/templates/images/shared-project@2x.png Binary files differindex ed94542853..fa5f8c3ad9 100644 --- a/main/src/core/MonoDevelop.Ide/templates/images/shared-project@2x.png +++ b/main/src/core/MonoDevelop.Ide/templates/images/shared-project@2x.png |