diff options
author | Sandy Armstrong <sandy@xamarin.com> | 2019-01-25 18:05:34 +0300 |
---|---|---|
committer | Sandy Armstrong <sandy@xamarin.com> | 2019-01-25 18:24:42 +0300 |
commit | 2325b5d4c5f79fcbe37acf617eb87e23c56a1684 (patch) | |
tree | f9c8fd4da08b7bbac6b26ef1602fd35ec7ac4bd9 /main/src/addins | |
parent | 4a92358ddf393435c36fb742aeecda2e45d9c238 (diff) | |
parent | 2e188887d8e5ee2901fd803d4374f0c0fb8ad69a (diff) |
Merge remote-tracking branch 'origin/master' into pr-sandy-md-master
Diffstat (limited to 'main/src/addins')
40 files changed, 592 insertions, 415 deletions
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.addin.xml b/main/src/addins/CSharpBinding/CSharpBinding.addin.xml index a0f29aa524..2d78c132f9 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.addin.xml +++ b/main/src/addins/CSharpBinding/CSharpBinding.addin.xml @@ -60,6 +60,7 @@ type="array" _label = "Refactory Operations" /> <Command id = "MonoDevelop.CSharp.Refactoring.Commands.SortAndRemoveImports" + defaultHandler = "MonoDevelop.CSharp.Refactoring.RemoveAndSortUsingsHandler" _label = "R_emove and Sort Usings" _displayName = "Remove Unused and Sort (Usings)" /> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs index c1288027a1..9dce8b43f9 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs @@ -106,6 +106,8 @@ namespace MonoDevelop.CSharp.Formatting indent.Editor.Options.IndentStyle == IndentStyle.Auto) return; var doc = indent.DocumentContext.AnalysisDocument; + if (doc == null) + return; var options = await doc.GetOptionsAsync (); if (!options.GetOption (FeatureOnOffOptions.FormatOnPaste, doc.Project.Language)) return; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/RefactoryCommands.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/RefactoryCommands.cs index 5dcca9c6f6..c20004ddbd 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/RefactoryCommands.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/RefactoryCommands.cs @@ -58,7 +58,70 @@ namespace MonoDevelop.CSharp.Refactoring SortAndRemoveImports, } - sealed class CurrentRefactoryOperationsHandler : CommandHandler + abstract class RefactoringHandler : CommandHandler + { + protected bool TryGetDocument (out Document analysisDocument, out Ide.Gui.Document doc) + { + doc = IdeApp.Workbench.ActiveDocument; + if (doc == null || doc.FileName == null) { + analysisDocument = null; + return false; + } + + analysisDocument = doc.AnalysisDocument; + return doc != null; + } + } + + sealed class RemoveAndSortUsingsHandler : RefactoringHandler + { + protected override void Update (CommandInfo info) + { + info.Enabled = TryGetDocument (out var doc, out var _) && IsSortAndRemoveImportsSupported (doc); + } + + protected override void Run () + { + if (TryGetDocument (out var doc, out var _)) + SortAndRemoveUnusedImports (doc, CancellationToken.None).Ignore (); + } + + internal static bool IsSortAndRemoveImportsSupported (Document document) + { + var workspace = document.Project.Solution.Workspace; + + if (!workspace.CanApplyChange (ApplyChangesKind.ChangeDocument)) { + return false; + } + + if (workspace.Kind == WorkspaceKind.MiscellaneousFiles) { + return false; + } + + return workspace.Services.GetService<IDocumentSupportsFeatureService> ().SupportsRefactorings (document); + } + + internal static async Task SortAndRemoveUnusedImports (Document originalDocument, CancellationToken cancellationToken) + { + if (originalDocument == null) + return; + + var workspace = originalDocument.Project.Solution.Workspace; + + var unnecessaryImportsService = originalDocument.GetLanguageService<IRemoveUnnecessaryImportsService> (); + + // Remove unnecessary imports and sort them + var removedImportsDocument = await unnecessaryImportsService.RemoveUnnecessaryImportsAsync (originalDocument, cancellationToken); + var resultDocument = await OrganizeImportsService.OrganizeImportsAsync (removedImportsDocument, cancellationToken); + + // Apply the document change if needed + if (resultDocument != originalDocument) { + workspace.ApplyDocumentChanges (resultDocument, cancellationToken); + } + } + } + + sealed class CurrentRefactoryOperationsHandler : RefactoringHandler { protected override void Run (object dataItem) { @@ -69,9 +132,7 @@ namespace MonoDevelop.CSharp.Refactoring protected override async Task UpdateAsync (CommandArrayInfo ainfo, CancellationToken cancelToken) { - var doc = IdeApp.Workbench.ActiveDocument; - var analysisDocument = doc.AnalysisDocument; - if (doc == null || doc.FileName == FilePath.Null || analysisDocument == null) + if (!TryGetDocument (out var analysisDocument, out var doc)) return; var semanticModel = await analysisDocument.GetSemanticModelAsync (cancelToken); if (semanticModel == null) @@ -87,12 +148,12 @@ namespace MonoDevelop.CSharp.Refactoring })); } - bool isSortAndRemoveUsingsSupported = IsSortAndRemoveImportsSupported (analysisDocument); + bool isSortAndRemoveUsingsSupported = RemoveAndSortUsingsHandler.IsSortAndRemoveImportsSupported (analysisDocument); if (isSortAndRemoveUsingsSupported) { var sortAndRemoveImportsInfo = IdeApp.CommandService.GetCommandInfo (Commands.SortAndRemoveImports); sortAndRemoveImportsInfo.Enabled = true; ainfo.Add (sortAndRemoveImportsInfo, new Action (async delegate { - await SortAndRemoveUnusedImports (analysisDocument, cancelToken); + await RemoveAndSortUsingsHandler.SortAndRemoveUnusedImports (analysisDocument, cancelToken); })); } @@ -140,40 +201,6 @@ namespace MonoDevelop.CSharp.Refactoring } } - static bool IsSortAndRemoveImportsSupported (Document document) - { - var workspace = document.Project.Solution.Workspace; - - if (!workspace.CanApplyChange (ApplyChangesKind.ChangeDocument)) { - return false; - } - - if (workspace.Kind == WorkspaceKind.MiscellaneousFiles) { - return false; - } - - return workspace.Services.GetService<IDocumentSupportsFeatureService> ().SupportsRefactorings (document); - } - - static async Task SortAndRemoveUnusedImports (Document originalDocument, CancellationToken cancellationToken) - { - if (originalDocument == null) - return; - - var workspace = originalDocument.Project.Solution.Workspace; - - var unnecessaryImportsService = originalDocument.GetLanguageService<IRemoveUnnecessaryImportsService> (); - - // Remove unnecessary imports and sort them - var removedImportsDocument = await unnecessaryImportsService.RemoveUnnecessaryImportsAsync (originalDocument, cancellationToken); - var resultDocument = await OrganizeImportsService.OrganizeImportsAsync (removedImportsDocument, cancellationToken); - - // Apply the document change if needed - if (resultDocument != originalDocument) { - workspace.ApplyDocumentChanges (resultDocument, cancellationToken); - } - } - static string FormatFileName (string fileName) { if (fileName == null) diff --git a/main/src/addins/Deployment/MonoDevelop.Deployment/MonoDevelop.Deployment/DefaultDeployServiceExtension.cs b/main/src/addins/Deployment/MonoDevelop.Deployment/MonoDevelop.Deployment/DefaultDeployServiceExtension.cs index 4cec8f48b9..ad47d39987 100644 --- a/main/src/addins/Deployment/MonoDevelop.Deployment/MonoDevelop.Deployment/DefaultDeployServiceExtension.cs +++ b/main/src/addins/Deployment/MonoDevelop.Deployment/MonoDevelop.Deployment/DefaultDeployServiceExtension.cs @@ -26,7 +26,7 @@ namespace MonoDevelop.Deployment evalCtx.ItemsToEvaluate.Add ("AllPublishItemsFullPathWithTargetPath"); if (project.MSBuildProject.UseMSBuildEngine) { - var result = project.RunTarget (null, "GetCopyToPublishDirectoryItems", configuration, evalCtx).Result; + var result = project.RunTarget (new ProgressMonitor (), "GetCopyToPublishDirectoryItems", configuration, evalCtx).Result; foreach (var item in result.Items) { if (item.Name == "AllPublishItemsFullPathWithTargetPath") { var fromPath = MSBuildProjectService.FromMSBuildPath (project.ItemDirectory, item.Include); diff --git a/main/src/addins/MacPlatform/MacInterop/LaunchServices.cs b/main/src/addins/MacPlatform/MacInterop/LaunchServices.cs index c8549b32fa..4a42e43f59 100644 --- a/main/src/addins/MacPlatform/MacInterop/LaunchServices.cs +++ b/main/src/addins/MacPlatform/MacInterop/LaunchServices.cs @@ -48,6 +48,7 @@ namespace MonoDevelop.MacInterop public string[] Args { get; set; } public bool Async { get; set; } public bool NewInstance { get; set; } + public bool HideFromRecentApps { get; set; } } public class LaunchServicesException : Exception @@ -144,6 +145,8 @@ namespace MonoDevelop.MacInterop options |= (UInt32) LaunchOptions.NSWorkspaceLaunchAsync; if (application.NewInstance) options |= (UInt32) LaunchOptions.NSWorkspaceLaunchNewInstance; + if (application.HideFromRecentApps) + options |= (UInt32) LaunchOptions.NSWorkspaceLaunchWithoutAddingToRecents; IntPtr error; var appHandle = IntPtr_objc_msgSend_IntPtr_UInt32_IntPtr_IntPtr (NSWorkspace.SharedWorkspace.Handle, launchApplicationAtURLOptionsConfigurationErrorSelector, appUrl.Handle, options, config.Handle, out error); diff --git a/main/src/addins/MacPlatform/MacInterop/ProcessManager.cs b/main/src/addins/MacPlatform/MacInterop/ProcessManager.cs index 6861c33696..565ed251a1 100644 --- a/main/src/addins/MacPlatform/MacInterop/ProcessManager.cs +++ b/main/src/addins/MacPlatform/MacInterop/ProcessManager.cs @@ -33,28 +33,6 @@ namespace MonoDevelop.MacInterop { public static class ProcessManager { - const string CARBON = "/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon"; - - [DllImport (CARBON)] - static extern OSStatus GetProcessPID (ref ProcessSerialNumber psn, out int pid); - - [DllImport (CARBON)] - static extern OSStatus KillProcess (ref ProcessSerialNumber process); - - public static int GetProcessPid (ProcessSerialNumber psn) - { - int pid; - if (GetProcessPID (ref psn, out pid) == OSStatus.Ok) - return pid; - return -1; - } - - [Obsolete ("Use KillProcess (int pid) instead")] - public static bool KillProcess (ProcessSerialNumber psn) - { - return KillProcess (ref psn) == OSStatus.Ok; - } - public static bool KillProcess (int pid) { NSRunningApplication runningApp = NSRunningApplication.GetRunningApplication (pid); @@ -74,20 +52,5 @@ namespace MonoDevelop.MacInterop Ok = 0 } } - - public struct ProcessSerialNumber - { - uint high; - uint low; - - public ProcessSerialNumber (uint high, uint low) - { - this.high = high; - this.low = low; - } - - public uint High { get { return high; } } - public uint Low { get { return low; } } - } } diff --git a/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs b/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs index ffaace2c12..d28760db4c 100644 --- a/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs +++ b/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs @@ -124,22 +124,10 @@ namespace MonoDevelop.MacIntegration.MainToolbar internal void OnSizeChanged () { - if (SizeChanged != null) { - SizeChanged (this, EventArgs.Empty); - } + SizeChanged?.Invoke (this, EventArgs.Empty); } - public override bool BecomeFirstResponder() - { - if (Window.FirstResponder != RealSelectorView) - return Window.MakeFirstResponder(RealSelectorView); - return false; - } - - public override bool AcceptsFirstResponder() - { - return Window.FirstResponder != RealSelectorView; - } + public override bool AcceptsFirstResponder () => false; #region PathSelectorView [Register] @@ -585,26 +573,26 @@ namespace MonoDevelop.MacIntegration.MainToolbar // 0x30 is Tab if (theEvent.KeyCode == (ushort)KeyCodes.Tab) { if ((theEvent.ModifierFlags & NSEventModifierMask.ShiftKeyMask) == NSEventModifierMask.ShiftKeyMask) { - focusedCellIndex--; - if (focusedCellIndex < 0) { + if (focusedCellIndex <= 0) { if (PreviousKeyView != null) { SetSelection (); focusedCellIndex = 0; focusedItem = null; } } else { + focusedCellIndex--; SetSelection (); return; } } else { - focusedCellIndex++; - if (focusedCellIndex >= VisibleCellIds.Length) { + if (focusedCellIndex >= VisibleCellIds.Length - 1) { if (NextKeyView != null) { SetSelection (); focusedCellIndex = 0; focusedItem = null; } } else { + focusedCellIndex++; SetSelection (); return; } @@ -616,15 +604,20 @@ namespace MonoDevelop.MacIntegration.MainToolbar void SetSelection () { - if (focusedItem != null) { - focusedItem.HasFocus = false; - } + //ensures our cells are in the correct enabled state if (focusedCellIndex >= 0 && focusedCellIndex < Cells.Length) { - var item = Cells [focusedCellIndex].Cell as NSPathComponentCellFocusable; - focusedItem = item; - if (item != null) - item.HasFocus = true; + focusedItem = Cells [focusedCellIndex].Cell as NSPathComponentCellFocusable; + if (focusedItem != null) + focusedItem.HasFocus = true; + } + + //we want ensure our state is correct in other elements + for (int i = 0; i < Cells.Length; i++) { + if (i != focusedCellIndex && Cells [i].Cell is NSPathComponentCellFocusable focusable) { + focusable.HasFocus = false; + } } + SetNeedsDisplay (); } diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/packages.config b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/packages.config new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/packages.config @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs index f852bfc07b..5800ba5fe4 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs @@ -830,7 +830,7 @@ namespace MonoDevelop.Debugger void UpdateDebugSessionCounter () { - var metadata = new Dictionary<string, string> (); + var metadata = new Dictionary<string, object> (); metadata ["Success"] = (!SessionError).ToString (); metadata ["DebuggerType"] = Engine.Id; @@ -843,7 +843,7 @@ namespace MonoDevelop.Debugger } } - Counters.DebugSession.Inc (metadata); + Counters.DebugSession.Inc (1, null, metadata); } void UpdateEvaluationStatsCounter () @@ -853,7 +853,7 @@ namespace MonoDevelop.Debugger return; } - var metadata = new Dictionary<string, string> (); + var metadata = new Dictionary<string, object> (); metadata ["DebuggerType"] = Engine.Id; metadata ["AverageDuration"] = Session.EvaluationStats.AverageTime.ToString (); metadata ["MaximumDuration"] = Session.EvaluationStats.MaxTime.ToString (); @@ -861,7 +861,7 @@ namespace MonoDevelop.Debugger metadata ["FailureCount"] = Session.EvaluationStats.FailureCount.ToString (); metadata ["SuccessCount"] = Session.EvaluationStats.TimingsCount.ToString (); - Counters.EvaluationStats.Inc (metadata); + Counters.EvaluationStats.Inc (1, null, metadata); } bool ExceptionHandler (Exception ex) diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Extensions.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Extensions.cs index b1a2498285..1364ab3939 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Extensions.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Extensions.cs @@ -65,6 +65,10 @@ namespace MonoDevelop.Debugger public static AsyncOperation DebugApplication (this ProjectOperations opers, string executableFile, string args, string workingDir, IDictionary<string,string> envVars) { + if (!IdeApp.Workbench.RootWindow.Visible) { + IdeApp.Workbench.RootWindow.Show (); + } + var monitor = IdeApp.Workbench.ProgressMonitors.GetRunProgressMonitor (System.IO.Path.GetFileName (executableFile)); var oper = DebuggingService.Run (executableFile, args, workingDir, envVars, monitor.Console); @@ -79,6 +83,10 @@ namespace MonoDevelop.Debugger public static AsyncOperation AttachToProcess (this ProjectOperations opers, DebuggerEngine debugger, ProcessInfo proc) { + if (!IdeApp.Workbench.RootWindow.Visible) { + IdeApp.Workbench.RootWindow.Show (); + } + var oper = DebuggingService.AttachToProcess (debugger, proc); opers.AddRunOperation (oper); diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs index 89db6240e6..8a5fb4f50e 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs @@ -2190,9 +2190,12 @@ namespace MonoDevelop.Debugger var val = (ObjectValue) store.GetValue (iter, ObjectColumn); if (val != null && val.Name == DebuggingService.DebuggerSession.EvaluationOptions.CurrentExceptionTag) DebuggingService.ShowExceptionCaughtDialog (); + + if (val != null && DebuggingService.HasValueVisualizers (val)) + DebuggingService.ShowValueVisualizer (val); } - - + + bool GetCellAtPos (int x, int y, out TreePath path, out TreeViewColumn col, out CellRenderer cellRenderer) { if (GetPathAtPos (x, y, out path, out col)) { diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/TextEntryWithCodeCompletion.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/TextEntryWithCodeCompletion.cs index ceb0633283..b68f8e5762 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/TextEntryWithCodeCompletion.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/TextEntryWithCodeCompletion.cs @@ -34,21 +34,18 @@ namespace MonoDevelop.Debugger class TextEntryWithCodeCompletion : TextEntry, ICompletionWidget { CodeCompletionContext ctx; - Gtk.Entry gtkEntry; - Gdk.ModifierType modifier; + Xwt.ModifierKeys modifier; bool keyHandled = false; uint keyValue; char keyChar; - Gdk.Key key; + Key key; public TextEntryWithCodeCompletion () { - gtkEntry = Xwt.Toolkit.CurrentEngine.GetNativeWidget (this) as Gtk.Entry; - if (gtkEntry == null) - throw new NotImplementedException (); - gtkEntry.KeyReleaseEvent += HandleKeyReleaseEvent; - gtkEntry.KeyPressEvent += HandleKeyPressEvent; + KeyPressed += HandleKeyPressEvent; + KeyReleased += HandleKeyReleaseEvent; + CompletionWindowManager.WindowClosed += HandleWindowClosed; } @@ -65,32 +62,40 @@ namespace MonoDevelop.Debugger CompletionContextChanged (this, EventArgs.Empty); } + char CharFromKey (Xwt.Key xwtKey) + { + if (xwtKey >= Key.Exclamation && xwtKey <= Key.Tilde) { + return (char)xwtKey; + } + + return '\0'; + } + [GLib.ConnectBeforeAttribute] - void HandleKeyPressEvent (object o, Gtk.KeyPressEventArgs args) + void HandleKeyPressEvent (object o, KeyEventArgs args) { keyHandled = false; - keyChar = (char)args.Event.Key; - keyValue = args.Event.KeyValue; - modifier = args.Event.State; - key = args.Event.Key; + keyChar = CharFromKey (args.Key); + modifier = args.Modifiers; + key = args.Key; - if ((args.Event.Key == Gdk.Key.Down || args.Event.Key == Gdk.Key.Up)) { + if ((args.Key == Key.Down || args.Key == Key.Up)) { keyChar = '\0'; } if (list != null) - args.RetVal = keyHandled = CompletionWindowManager.PreProcessKeyEvent (KeyDescriptor.FromGtk (key, keyChar, modifier)); + args.Handled = keyHandled = CompletionWindowManager.PreProcessKeyEvent (KeyDescriptor.FromXwt (key, keyChar, modifier)); } - void HandleKeyReleaseEvent (object o, Gtk.KeyReleaseEventArgs args) + void HandleKeyReleaseEvent (object o, KeyEventArgs args) { if (keyHandled) return; string text = ctx == null ? Text : Text.Substring (Math.Max (0, Math.Min (ctx.TriggerOffset, Text.Length))); CompletionWindowManager.UpdateWordSelection (text); - CompletionWindowManager.PostProcessKeyEvent (KeyDescriptor.FromGtk (key, keyChar, modifier)); + CompletionWindowManager.PostProcessKeyEvent (KeyDescriptor.FromXwt (key, keyChar, modifier)); PopupCompletion (); } @@ -121,7 +126,7 @@ namespace MonoDevelop.Debugger /// </summary> class NullDotKeyHandler : ICompletionKeyHandler { - #region ICompletionKeyHandler implementation +#region ICompletionKeyHandler implementation public bool PreProcessKey (CompletionListWindow listWindow, KeyDescriptor descriptor, out KeyActions keyAction) { @@ -141,10 +146,10 @@ namespace MonoDevelop.Debugger return false; } - #endregion +#endregion } - #region ICompletionWidget implementation +#region ICompletionWidget implementation public event EventHandler CompletionContextChanged; @@ -186,11 +191,11 @@ namespace MonoDevelop.Debugger public CodeCompletionContext CreateCodeCompletionContext (int triggerOffset) { - var height = gtkEntry.SizeRequest ().Height; + var height = Size.Height; var location = ConvertToScreenCoordinates (new Point (0, height)); return new CodeCompletionContext ( - (int)location.X, (int)location.Y, height, + (int)location.X, (int)location.Y, (int)height, triggerOffset, 0, triggerOffset, CaretOffset ); } @@ -203,13 +208,13 @@ namespace MonoDevelop.Debugger public void SetCompletionText (CodeCompletionContext ctx, string partial_word, string complete_word) { Text = complete_word; - gtkEntry.Position = complete_word.Length; + CursorPosition = complete_word.Length; } public void SetCompletionText (CodeCompletionContext ctx, string partial_word, string complete_word, int completeWordOffset) { Text = complete_word; - gtkEntry.Position = complete_word.Length; + CursorPosition = complete_word.Length; } public CodeCompletionContext CurrentCodeCompletionContext { @@ -220,10 +225,10 @@ namespace MonoDevelop.Debugger public int CaretOffset { get { - return gtkEntry.Position; + return CursorPosition; } set { - gtkEntry.Position = value; + CursorPosition = value; } } @@ -241,7 +246,7 @@ namespace MonoDevelop.Debugger public Gtk.Style GtkStyle { get { - return gtkEntry.Style; + return null; } } @@ -250,7 +255,7 @@ namespace MonoDevelop.Debugger return 1; } } - #endregion +#endregion } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/CodeTemplateToolboxProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/CodeTemplateToolboxProvider.cs index 5ed2482524..e65e76b079 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/CodeTemplateToolboxProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/CodeTemplateToolboxProvider.cs @@ -40,7 +40,6 @@ namespace MonoDevelop.DesignerSupport.Toolbox { static string category = MonoDevelop.Core.GettextCatalog.GetString ("Text Snippets"); - public System.Collections.Generic.IEnumerable<ItemToolboxNode> GetDynamicItems (IToolboxConsumer consumer) { var content = consumer as ViewContent; @@ -58,7 +57,7 @@ namespace MonoDevelop.DesignerSupport.Toolbox }; } } - + public event EventHandler ItemsChanged { add { CodeTemplateService.TemplatesChanged += value; } remove { CodeTemplateService.TemplatesChanged -= value; } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/IToolboxProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/IToolboxProvider.cs index 3498dccd20..041c9cf194 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/IToolboxProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/IToolboxProvider.cs @@ -35,7 +35,13 @@ using System.Collections.Generic; namespace MonoDevelop.DesignerSupport.Toolbox { - + public interface IToolboxDynamicProviderDeleteSupport + { + bool DeleteDynamicItem (ItemToolboxNode node); + + bool CanDeleteDynamicItem (ItemToolboxNode node); + } + //Used to fetch or generate the default toolbox items at the beginning of each MD session public interface IToolboxDefaultProvider { @@ -53,7 +59,7 @@ namespace MonoDevelop.DesignerSupport.Toolbox //This method will be called each time the consumer changes. Return null if not //returning any items for a specific consumer. IEnumerable<ItemToolboxNode> GetDynamicItems (IToolboxConsumer consumer); - + event EventHandler ItemsChanged; } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolbox.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolbox.cs index f96b00e16f..470addae0c 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolbox.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolbox.cs @@ -447,7 +447,7 @@ namespace MonoDevelop.DesignerSupport.Toolbox { // Hack manually filter out gtk# widgets & container since they cannot be re added // because they're missing the toolbox attributes. - info.Enabled = selectedNode != null + info.Enabled = selectedNode != null && toolboxService.CanRemoveUserItem (selectedNode) && (selectedNode.ItemDomain != GtkWidgetDomain || (selectedNode.Category != "Widgets" && selectedNode.Category != "Container")); } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolboxWidget.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolboxWidget.cs index 63562a7689..361798aca1 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolboxWidget.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/MacToolboxWidget.cs @@ -255,6 +255,7 @@ namespace MonoDevelop.DesignerSupport.Toolbox base.SetFrameSize (newSize); var frame = messageTextField.Frame; messageTextField.Frame = new CGRect (frame.Location, newSize); + RedrawItems (true, false); } public override void MouseDown (NSEvent theEvent) @@ -344,12 +345,6 @@ namespace MonoDevelop.DesignerSupport.Toolbox RegisterClassForItem (typeof (HeaderCollectionViewItem), HeaderViewItemName); RegisterClassForItem (typeof (LabelCollectionViewItem), LabelViewItemName); RegisterClassForItem (typeof (ImageCollectionViewItem), ImageViewItemName); - - NSNotificationCenter.DefaultCenter.AddObserver (FrameChangedNotification, (s => { - if (s.Object == this) { - RedrawItems (true, false); - } - })); } protected override void Dispose (bool disposing) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxService.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxService.cs index ec9c9db283..fbfe40baee 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxService.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/ToolboxService.cs @@ -152,8 +152,16 @@ namespace MonoDevelop.DesignerSupport public void RemoveUserItem (ItemToolboxNode node) { - Configuration.ItemList.Remove (node); - SaveConfiguration (); + if (Configuration.ItemList.Remove (node)) { + SaveConfiguration (); + } else { + //we need check in the dynamic providers + foreach (var prov in dynamicProviders) { + if (prov is IToolboxDynamicProviderDeleteSupport provDelSupport && provDelSupport.DeleteDynamicItem (node)) { + break; + } + } + } OnToolboxContentsChanged (); } @@ -526,7 +534,22 @@ namespace MonoDevelop.DesignerSupport //we assume permitted, so only return false when blocked by a filter return true; } - + + internal bool CanRemoveUserItem (ItemToolboxNode node) + { + if (Configuration.ItemList.Contains (node)) { + return true; + } else { + //we need check in the dynamic providers + foreach (var prov in dynamicProviders) { + if (prov is IToolboxDynamicProviderDeleteSupport provDelSupport && provDelSupport.CanDeleteDynamicItem (node)) { + return true; + } + } + } + return false; + } + //evaluate a filter attribute against a list, and check whether permitted private bool FilterPermitted (ItemToolboxNode node, ToolboxItemFilterAttribute desFa, ICollection<ToolboxItemFilterAttribute> filterAgainst, IToolboxConsumer consumer) diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Gui/DotNetCoreSdkLocationWidget.UI.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Gui/DotNetCoreSdkLocationWidget.UI.cs index 247746fe46..1221d49c2e 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Gui/DotNetCoreSdkLocationWidget.UI.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Gui/DotNetCoreSdkLocationWidget.UI.cs @@ -80,6 +80,14 @@ namespace MonoDevelop.DotNetCore.Gui locationBox.PackStart (locationLabel, false, false); locationFileSelector = new CustomFileSelector (); + locationFileSelector.TextEntry.SetCommonAccessibilityAttributes ( + "DotNetCoreSdkLocationWidget.Location", + locationLabel.Text, + GettextCatalog.GetString ("Enter the .NET Core SDK location")); + locationFileSelector.BrowseButton.SetCommonAccessibilityAttributes ( + "DotNetCoreSdkLocationWidget.Browse", + GettextCatalog.GetString ("Browse"), + GettextCatalog.GetString ("Select a folder for the .NET Core SDK location")); locationBox.PackStart (locationFileSelector, true, true); // .NET Core SDK section. @@ -148,7 +156,7 @@ namespace MonoDevelop.DotNetCore.Gui void UpdateCommandLineIconAccessibility (bool found) { - sdkFoundIcon.SetCommonAccessibilityAttributes ( + commandLineFoundIcon.SetCommonAccessibilityAttributes ( "DotNetCoreCommandLineFoundImage", found ? GettextCatalog.GetString ("A Tick") : GettextCatalog.GetString ("A Cross"), found ? GettextCatalog.GetString ("The .NET Core command line was found") : GettextCatalog.GetString ("The .NET Core command line was not found")); @@ -171,6 +179,7 @@ namespace MonoDevelop.DotNetCore.Gui class CustomFileSelector : Widget { TextEntry entry; + Button browseButton; FileDialog dialog; string currentFolder; string title; @@ -182,13 +191,21 @@ namespace MonoDevelop.DotNetCore.Gui entry.Changed += EntryChanged; box.PackStart (entry, true); - var browseButton = new Button ("…"); + browseButton = new Button ("…"); box.PackStart (browseButton); browseButton.Clicked += BrowseButtonClicked; Content = box; } + internal TextEntry TextEntry { + get { return entry; } + } + + internal Button BrowseButton { + get { return browseButton; } + } + public string CurrentFolder { get { return dialog != null ? dialog.CurrentFolder : currentFolder; diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs index 75efb748ab..bd7cf6e50d 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs @@ -88,11 +88,10 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; Assert.AreEqual ("15.0", project.ToolsVersion); Assert.IsFalse (project.IsOutputTypeDefined); - Assert.AreEqual ("Microsoft.NET.Sdk", project.Sdk); Assert.IsTrue (project.HasSdk); } @@ -115,6 +114,24 @@ namespace MonoDevelop.DotNetCore.Tests } [Test] + public void ReadProject_ExplicityReferences () + { + CreateMSBuildProject ( + "<Project ToolsVersion=\"15.0\">\r\n" + + " <PropertyGroup>\r\n" + + " <OutputType>Exe</OutputType>\r\n" + + " <TargetFramework>netcoreapp1.0</TargetFramework>\r\n" + + " </PropertyGroup>\r\n" + + " <Import Sdk=\"Microsoft.NET.Sdk\" Project=\"Sdk.targets\" />" + + "</Project>"); + msbuildProject.Evaluate (); + + ReadProject (); + + Assert.That (msbuildProject.GetReferencedSDKs (), Is.Not.Empty); + } + + [Test] public void WriteProject_ProjectGuidAddedAndToolsVersionChanged_ProjectGuidIsRemovedAndToolsVersionReset () { CreateMSBuildProject ( @@ -313,7 +330,7 @@ namespace MonoDevelop.DotNetCore.Tests " </PropertyGroup>\r\n" + "</Project>"); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; msbuildProject.ToolsVersion = "4.0"; WriteProject (); @@ -332,7 +349,7 @@ namespace MonoDevelop.DotNetCore.Tests " </PropertyGroup>\r\n" + "</Project>"); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; var projectReferenceItem = msbuildProject.AddNewItem ("ProjectReference", @"Lib\Lib.csproj"); projectReferenceItem.Metadata.SetValue ("Name", "Lib"); projectReferenceItem.Metadata.SetValue ("Project", "{F109E7DF-F561-4CD6-A46E-CFB27A8B6F2C}"); @@ -359,7 +376,7 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); msbuildProject.Evaluate (); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; WriteProject (".NETCoreApp,Version=v1.1"); @@ -380,7 +397,7 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); msbuildProject.Evaluate (); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; WriteProject (".NETCoreApp,Version=v1.1"); WriteProject (".NETCoreApp,Version=v1.0"); @@ -402,7 +419,7 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); msbuildProject.Evaluate (); ReadProject (".NET Standard,Version=v1.0"); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; WriteProject (".NETStandard,Version=v1.6"); @@ -423,7 +440,7 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); msbuildProject.Evaluate (); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; WriteProject (".NETFramework,Version=v4.6"); @@ -444,7 +461,7 @@ namespace MonoDevelop.DotNetCore.Tests "</Project>"); msbuildProject.Evaluate (); ReadProject (); - project.Sdk = "Microsoft.NET.Sdk"; + project.HasSdk = true; WriteProject (".NETCoreApp,Version=v1.1"); diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs index da870db57f..0034e373fd 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs @@ -45,24 +45,14 @@ namespace MonoDevelop.DotNetCore public string ToolsVersion { get; private set; } public bool IsOutputTypeDefined { get; private set; } - public string Sdk { get; set; } - public IEnumerable<string> TargetFrameworks { - get { return targetFrameworks; } - } + public IEnumerable<string> TargetFrameworks => targetFrameworks; - public bool HasSdk { - get { return Sdk != null; } - } + public bool HasSdk { get; set; } - public bool HasToolsVersion () - { - return !string.IsNullOrEmpty (ToolsVersion); - } + public bool HasToolsVersion () => !string.IsNullOrEmpty (ToolsVersion); - public CompileTarget DefaultCompileTarget { - get { return defaultCompileTarget; } - } + public CompileTarget DefaultCompileTarget => defaultCompileTarget; /// <summary> /// Ensure MSBuildProject has ToolsVersion set to 15.0 so the correct diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs index 92872f158b..d51f3c8538 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs @@ -93,7 +93,7 @@ namespace MonoDevelop.DotNetCore /// </summary> bool IsSdkProject (DotNetProject project) { - return project.MSBuildProject.GetReferencedSDKs ().Any (); + return project.MSBuildProject.GetReferencedSDKs ().Length > 0; } protected override bool OnGetCanReferenceProject (DotNetProject targetProject, out string reason) @@ -409,7 +409,12 @@ namespace MonoDevelop.DotNetCore if (ProjectNeedsRestore ()) { return CreateNuGetRestoreRequiredBuildResult (); } - if ((HasSdk && !IsDotNetCoreSdkInstalled ()) || (HasSdk && sdkPaths.IsUnsupportedSdkVersion)) { + + if (!Project.TargetFramework.Id.IsNetStandardOrNetCoreApp ()) { + return null; + } + + if ((HasSdk && !IsDotNetCoreSdkInstalled ()) || (sdkPaths != null && sdkPaths.IsUnsupportedSdkVersion)) { return CreateDotNetCoreSdkRequiredBuildResult (); } return null; @@ -468,13 +473,10 @@ namespace MonoDevelop.DotNetCore protected override void OnBeginLoad () { - dotNetCoreMSBuildProject.Sdk = Project.MSBuildProject.Sdk; base.OnBeginLoad (); } - public bool HasSdk { - get { return dotNetCoreMSBuildProject.HasSdk; } - } + public bool HasSdk => Project.MSBuildProject.GetReferencedSDKs ().Length > 0; protected bool IsWebProject (DotNetProject project) { @@ -491,10 +493,11 @@ namespace MonoDevelop.DotNetCore if (!HasSdk) return; - - sdkPaths = DotNetCoreSdk.FindSdkPaths (dotNetCoreMSBuildProject.Sdk); - } + var referencedSdks = project.GetReferencedSDKs (); + sdkPaths = DotNetCoreSdk.FindSdkPaths (referencedSdks); + dotNetCoreMSBuildProject.HasSdk = referencedSdks.Length > 0; + } protected override async Task<ImmutableArray<ProjectFile>> OnGetSourceFiles (ProgressMonitor monitor, ConfigurationSelector configuration) { var sourceFiles = await base.OnGetSourceFiles (monitor, configuration); @@ -608,7 +611,14 @@ namespace MonoDevelop.DotNetCore bool IsFSharpSdkProject () { - return HasSdk && dotNetCoreMSBuildProject.Sdk.Contains ("FSharp"); + if (HasSdk) { + var sdks = Project.MSBuildProject.GetReferencedSDKs (); + for (var i = 0; i < sdks.Length; i++) { + if (sdks [i].Contains ("FSharp")) + return true; + } + } + return false; } /// <summary> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs index df0ef2a820..3da4bca039 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs @@ -82,9 +82,9 @@ namespace MonoDevelop.DotNetCore { } - internal static DotNetCoreSdkPaths FindSdkPaths (string sdk) + internal static DotNetCoreSdkPaths FindSdkPaths (string[] sdks) { - sdkPaths.FindSdkPaths (sdk); + sdkPaths.FindSdkPaths (sdks); return sdkPaths; } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdkPaths.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdkPaths.cs index 87122fbd1a..b41d895b9c 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdkPaths.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdkPaths.cs @@ -119,12 +119,12 @@ namespace MonoDevelop.DotNetCore IsUnsupportedSdkVersion = false; } - public void FindSdkPaths (string sdk) + public void FindSdkPaths (string [] sdks) { if (string.IsNullOrEmpty (MSBuildSDKsPath)) return; - Exist = CheckSdksExist (sdk); + Exist = CheckSdksExist (sdks); if (Exist) { IsUnsupportedSdkVersion = !CheckIsSupportedSdkVersion (SdksParentDirectory); @@ -149,18 +149,13 @@ namespace MonoDevelop.DotNetCore string SdksParentDirectory { get; set; } - static IEnumerable<string> SplitSdks (string sdk) => sdk.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); - - bool CheckSdksExist (string sdk) + bool CheckSdksExist (string[] sdks) { - if (sdk.Contains (';')) { - foreach (string sdkItem in SplitSdks (sdk)) { - if (!SdkPathExists (sdkItem)) - return false; - } - return true; + foreach (string sdkItem in sdks) { + if (!SdkPathExists (sdkItem)) + return false; } - return SdkPathExists (sdk); + return true; } bool SdkPathExists (string sdk) @@ -238,10 +233,14 @@ namespace MonoDevelop.DotNetCore using (var r = new StreamReader (GlobalJsonPath)) { try { var token = JObject.Parse (r.ReadToEnd ()); - if (token == null) - return string.Empty; - var version = (string)token.SelectToken ("sdk").SelectToken ("version"); - return version; + + if (token != null && token.TryGetValue ("sdk", out var sdkToken)) { + var version = sdkToken ["version"]; + if (version != null) + return version.Value<string>(); + } + + return string.Empty; } catch (Exception e) { LoggingService.LogWarning ($"Unable to parse {GlobalJsonPath}.", e); return string.Empty; diff --git a/main/src/addins/MonoDevelop.GtkCore/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs b/main/src/addins/MonoDevelop.GtkCore/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs index 1616424340..2df3434088 100644 --- a/main/src/addins/MonoDevelop.GtkCore/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs +++ b/main/src/addins/MonoDevelop.GtkCore/MonoDevelop.GtkCore.GuiBuilder/ToolboxProvider.cs @@ -14,7 +14,7 @@ using MonoDevelop.Components; namespace MonoDevelop.GtkCore.GuiBuilder { - public class ToolboxProvider: IToolboxDynamicProvider, IToolboxDefaultProvider + public class ToolboxProvider: IToolboxDynamicProvider, IToolboxDefaultProvider, IToolboxDynamicProviderDeleteSupport { internal static ToolboxProvider Instance; @@ -82,7 +82,11 @@ namespace MonoDevelop.GtkCore.GuiBuilder { yield return typeof(Stetic.Wrapper.Widget).Assembly.Location; } - + + public virtual bool DeleteDynamicItem (ItemToolboxNode node) => false; + + public virtual bool CanDeleteDynamicItem (ItemToolboxNode node) => false; + public event EventHandler ItemsChanged; } diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs index bdea66542d..c6bf1290fc 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs @@ -37,6 +37,8 @@ using Xwt; using Mono.MHex.Data; using Mono.MHex.Rendering; using Xwt.Drawing; +using MonoDevelop.Components.AtkCocoaHelper; +using MonoDevelop.Core; namespace Mono.MHex { @@ -99,8 +101,14 @@ namespace Mono.MHex } } + public bool IsReadOnly { get; set; } + + readonly Gtk.Widget hexWidget; + public HexEditor () { + hexWidget = (Gtk.Widget)Xwt.Toolkit.CurrentEngine.GetNativeWidget (this); + BackgroundColor = Color.FromBytes (0, 0, 0); CanGetFocus = true; HexEditorData = new HexEditorData (); @@ -112,6 +120,7 @@ namespace Mono.MHex if (HexEditorData.Caret.AutoScrollToCaret) ScrollToCaret (); RepaintLine (HexEditorData.Caret.Line); + AnnounceCurrentSelection (); }; HexEditorData.Caret.OffsetChanged += delegate(object sender, CaretLocationEventArgs e) { if (!HexEditorData.Caret.PreserveSelection) @@ -516,6 +525,17 @@ namespace Mono.MHex requestResetCaretBlink = true; } + void AnnounceCurrentSelection () + { + try { + var character = HexEditorData.Bytes [HexEditorData.Caret.Offset]; + var data = Convert.ToString (character, 16); + var message = GettextCatalog.GetString ("Selected '{0}' char:'{1}'", data [HexEditorData.Caret.SubPosition], (char)character); + hexWidget.Accessible.MakeAccessibilityAnnouncement (message); + } catch { + } + } + public void DrawCaret (Context ctx, Rectangle area) { if (!caretBlink || HexEditorData.IsSomethingSelected) diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditorDebugger.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditorDebugger.cs index 28bac51da9..68e508820b 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditorDebugger.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditorDebugger.cs @@ -80,6 +80,8 @@ namespace Mono.MHex comboBox.Items.Add ("Hex 16"); comboBox.SelectedIndex = 0; editor.Options.StringRepresentationType = StringRepresentationTypes.ASCII; + editor.Accessible.Label = GettextCatalog.GetString ("Hexadecimal Text Editor"); + comboBox.SelectionChanged += delegate { switch (comboBox.SelectedIndex) { case 0: diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs index 6b16f35e5b..29db8e9ab0 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs @@ -184,8 +184,10 @@ namespace Mono.MHex keyBindings [keyCode] (HexEditorData); return; } - - InsertCharacter (unicodeChar); + + if (!Editor.IsReadOnly) { + InsertCharacter (unicodeChar); + } } void InsertCharacter (uint unicodeChar) diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorVisualizer.cs b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorVisualizer.cs index 7897809fdd..40c0f444db 100644 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorVisualizer.cs +++ b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorVisualizer.cs @@ -130,7 +130,7 @@ namespace MonoDevelop.HexEditor } hexEditor.HexEditorData.Buffer = buffer; - hexEditor.Editor.Sensitive = CanEdit (val); + hexEditor.Editor.IsReadOnly = !CanEdit (val); var xwtScrollView = new Xwt.ScrollView (hexEditor); var scrollWidget = (Widget) Xwt.Toolkit.CurrentEngine.GetNativeWidget (xwtScrollView); diff --git a/main/src/addins/MonoDevelop.Packaging/Gui/MonoDevelop.Packaging.Gui.GtkNuGetPackageMetadataOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.Packaging/Gui/MonoDevelop.Packaging.Gui.GtkNuGetPackageMetadataOptionsPanelWidget.cs index 49a3bd30d5..7af75f47b5 100644 --- a/main/src/addins/MonoDevelop.Packaging/Gui/MonoDevelop.Packaging.Gui.GtkNuGetPackageMetadataOptionsPanelWidget.cs +++ b/main/src/addins/MonoDevelop.Packaging/Gui/MonoDevelop.Packaging.Gui.GtkNuGetPackageMetadataOptionsPanelWidget.cs @@ -48,7 +48,7 @@ namespace MonoDevelop.Packaging.Gui private global::Gtk.HBox packageLanguageHBox; - private global::Gtk.ComboBoxEntry packageLanguageComboBox; + private global::Gtk.ComboBox packageLanguageComboBox; private global::Gtk.Label packageLanguageLabel; @@ -321,7 +321,7 @@ namespace MonoDevelop.Packaging.Gui this.packageLanguageHBox.Name = "packageLanguageHBox"; this.packageLanguageHBox.Spacing = 6; // Container child packageLanguageHBox.Gtk.Box+BoxChild - this.packageLanguageComboBox = global::Gtk.ComboBoxEntry.NewText(); + this.packageLanguageComboBox = global::Gtk.ComboBox.NewText(); this.packageLanguageComboBox.Name = "packageLanguageComboBox"; this.packageLanguageHBox.Add(this.packageLanguageComboBox); global::Gtk.Box.BoxChild w19 = ((global::Gtk.Box.BoxChild)(this.packageLanguageHBox[this.packageLanguageComboBox])); diff --git a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs index 3f6f091de5..8e2ab47e58 100644 --- a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs +++ b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs @@ -42,6 +42,8 @@ namespace MonoDevelop.Packaging.Gui NuGetPackageMetadata metadata; bool projectOriginallyHadMetadata; bool hasPackageId; + List<CultureInfo> languages; + ListStore languagesListStore; public GtkNuGetPackageMetadataOptionsPanelWidget () { @@ -58,85 +60,68 @@ namespace MonoDevelop.Packaging.Gui packageReleaseNotesPaddingLabel.Accessible.Role = Atk.Role.Filler; packageIdTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.ID", - GettextCatalog.GetString ("ID"), - GettextCatalog.GetString ("Enter the ID of the NuGet package")); - packageIdTextBox.SetAccessibilityLabelRelationship (packageIdLabel); + packageIdLabel, + GettextCatalog.GetString ("Enter the ID of the NuGet package")); packageVersionTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Version", - GettextCatalog.GetString ("Version"), - GettextCatalog.GetString ("Enter the version of the NuGet package")); - packageVersionTextBox.SetAccessibilityLabelRelationship (packageVersionLabel); + packageVersionLabel, + GettextCatalog.GetString ("Enter the version of the NuGet package")); packageAuthorsTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Authors", - GettextCatalog.GetString ("Authors"), - GettextCatalog.GetString ("Enter the authors of the NuGet package")); - packageAuthorsTextBox.SetAccessibilityLabelRelationship (packageAuthorsLabel); + packageAuthorsLabel, + GettextCatalog.GetString ("Enter the authors of the NuGet package")); packageDescriptionTextView.SetCommonAccessibilityAttributes ("NuGetMetadata.Description", - GettextCatalog.GetString ("Description"), - GettextCatalog.GetString ("Enter the description of the NuGet package")); - packageDescriptionTextView.SetAccessibilityLabelRelationship (packageDescriptionLabel); + packageDescriptionLabel, + GettextCatalog.GetString ("Enter the description of the NuGet package")); packageOwnersTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Owners", - GettextCatalog.GetString ("Owners"), - GettextCatalog.GetString ("Enter the owners of the NuGet package")); - packageOwnersTextBox.SetAccessibilityLabelRelationship (packageOwnersLabel); + packageOwnersLabel, + GettextCatalog.GetString ("Enter the owners of the NuGet package")); packageCopyrightTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Copyright", - GettextCatalog.GetString ("Copyright"), - GettextCatalog.GetString ("Enter the copyright statement for the NuGet package")); - packageCopyrightTextBox.SetAccessibilityLabelRelationship (packageCopyrightLabel); + packageCopyrightLabel, + GettextCatalog.GetString ("Enter the copyright statement for the NuGet package")); packageTitleTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Title", - GettextCatalog.GetString ("Title"), - GettextCatalog.GetString ("Enter the title of the NuGet package")); - packageTitleTextBox.SetAccessibilityLabelRelationship (packageTitleLabel); + packageTitleLabel, + GettextCatalog.GetString ("Enter the title of the NuGet package")); packageSummaryTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Summary", - GettextCatalog.GetString ("Summary"), - GettextCatalog.GetString ("Enter the summary for the NuGet package")); - packageSummaryTextBox.SetAccessibilityLabelRelationship (packageSummaryLabel); + packageSummaryLabel, + GettextCatalog.GetString ("Enter the summary for the NuGet package")); packageProjectUrlTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.URL", - GettextCatalog.GetString ("Project URL"), - GettextCatalog.GetString ("Enter the project URL for the NuGet package")); - packageProjectUrlTextBox.SetAccessibilityLabelRelationship (packageProjectUrlLabel); + packageProjectUrlLabel, + GettextCatalog.GetString ("Enter the project URL for the NuGet package")); packageIconUrlTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Icon", - GettextCatalog.GetString ("Icon URL"), - GettextCatalog.GetString ("Enter the URL for the NuGet package's icon")); - packageIconUrlTextBox.SetAccessibilityLabelRelationship (packageIconUrlLabel); + packageIconUrlLabel, + GettextCatalog.GetString ("Enter the URL for the NuGet package's icon")); packageLicenseUrlTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.licence", - GettextCatalog.GetString ("License URL"), - GettextCatalog.GetString ("Enter the URL for the NuGet package's license")); - packageLicenseUrlTextBox.SetAccessibilityLabelRelationship (packageLicenseUrlLabel); + packageLicenseUrlLabel, + GettextCatalog.GetString ("Enter the URL for the NuGet package's license")); packageRequireLicenseAcceptanceCheckBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Acceptance", - GettextCatalog.GetString ("Require License Acceptance"), - GettextCatalog.GetString ("Check to require the user to accept the NuGet package's license")); - packageRequireLicenseAcceptanceCheckBox.SetAccessibilityLabelRelationship (packageRequireLicenseAcceptanceLabel); + packageRequireLicenseAcceptanceLabel, + GettextCatalog.GetString ("Check to require the user to accept the NuGet package's license")); packageDevelopmentDependencyCheckBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Development", - GettextCatalog.GetString ("Development Dependency"), - GettextCatalog.GetString ("Check to indicate that this is a development dependency")); - packageDevelopmentDependencyCheckBox.SetAccessibilityLabelRelationship (packageDevelopmentDependencyLabel); + packageDevelopmentDependencyLabel, + GettextCatalog.GetString ("Check to indicate that this is a development dependency")); packageTagsTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Tags", - GettextCatalog.GetString ("Tags"), - GettextCatalog.GetString ("Enter the tags for this NuGet package")); - packageTagsTextBox.SetAccessibilityLabelRelationship (packageTagsLabel); + packageTagsLabel, + GettextCatalog.GetString ("Enter the tags for this NuGet package")); packageLanguageComboBox.SetCommonAccessibilityAttributes ("NuGetMetadata.Language", - GettextCatalog.GetString ("Language"), - GettextCatalog.GetString ("Select the language for this NuGet package")); - packageLanguageComboBox.SetAccessibilityLabelRelationship (packageLanguageLabel); + packageLanguageLabel, + GettextCatalog.GetString ("Select the language for this NuGet package")); packageReleaseNotesTextView.SetCommonAccessibilityAttributes ("NuGetMetadata.ReleaseNotes", - GettextCatalog.GetString ("Release Notes"), - GettextCatalog.GetString ("Enter the release notes for this NuGet package")); - packageReleaseNotesTextView.SetAccessibilityLabelRelationship (packageReleaseNotesLabel); - + packageReleaseNotesLabel, + GettextCatalog.GetString ("Enter the release notes for this NuGet package")); } internal static System.Action<bool> OnProjectHasMetadataChanged; @@ -168,7 +153,7 @@ namespace MonoDevelop.Packaging.Gui packageCopyrightTextBox.Text = GetTextBoxText (metadata.Copyright); packageDevelopmentDependencyCheckBox.Active = metadata.DevelopmentDependency; packageIconUrlTextBox.Text = GetTextBoxText (metadata.IconUrl); - packageLanguageComboBox.Entry.Text = GetTextBoxText (metadata.Language); + LoadLanguage (metadata.Language); packageLicenseUrlTextBox.Text = GetTextBoxText (metadata.LicenseUrl); packageOwnersTextBox.Text = GetTextBoxText (metadata.Owners); packageProjectUrlTextBox.Text = GetTextBoxText (metadata.ProjectUrl); @@ -184,6 +169,35 @@ namespace MonoDevelop.Packaging.Gui return text ?? string.Empty; } + void LoadLanguage (string language) + { + if (string.IsNullOrEmpty (language)) { + packageLanguageComboBox.Active = 0; + return; + } + + int index = GetLanguageIndex (language); + if (index >= 0) { + packageLanguageComboBox.Active = index + 1; + return; + } + + // Language does not match so we need to add it to the combo box. + TreeIter iter = languagesListStore.AppendValues (language); + packageLanguageComboBox.SetActiveIter (iter); + } + + int GetLanguageIndex (string language) + { + for (int i = 0; i < languages.Count; ++i) { + CultureInfo culture = languages [i]; + if (string.Equals (culture.Name, language, StringComparison.OrdinalIgnoreCase)) { + return i; + } + } + return -1; + } + internal void Save (PackagingProject project) { UpdateMetadata (); @@ -220,7 +234,7 @@ namespace MonoDevelop.Packaging.Gui metadata.Copyright = packageCopyrightTextBox.Text; metadata.DevelopmentDependency = packageDevelopmentDependencyCheckBox.Active; metadata.IconUrl = packageIconUrlTextBox.Text; - metadata.Language = packageLanguageComboBox.Entry.Text; + metadata.Language = GetSelectedLanguage (); metadata.LicenseUrl = packageLicenseUrlTextBox.Text; metadata.Owners = packageOwnersTextBox.Text; metadata.ProjectUrl = packageProjectUrlTextBox.Text; @@ -231,20 +245,49 @@ namespace MonoDevelop.Packaging.Gui metadata.Title = packageTitleTextBox.Text; } + string GetSelectedLanguage () + { + if (packageLanguageComboBox.Active == 0) { + // 'None' selected. + return string.Empty; + } + + int languageIndex = packageLanguageComboBox.Active - 1; + if (languageIndex < languages.Count) { + return languages [languageIndex].Name; + } + + // No match for language so just return the combo box text. + return packageLanguageComboBox.ActiveText; + } + void PopulateLanguages () { - var languagesListStore = new ListStore (typeof (string)); + languagesListStore = new ListStore (typeof (string)); packageLanguageComboBox.Model = languagesListStore; - List<string> languages = CultureInfo.GetCultures(CultureTypes.AllCultures) - .Select (c => c.Name) - .ToList (); + languages = new List<CultureInfo> (); - languages.Sort (); + foreach (CultureInfo culture in CultureInfo.GetCultures (CultureTypes.AllCultures)) { + if (!string.IsNullOrEmpty (culture.Name)) { + languages.Add (culture); + } + } - foreach (string language in languages) { - languagesListStore.AppendValues (language); + languages.Sort (CompareLanguages); + + languagesListStore.AppendValues (GettextCatalog.GetString ("None")); + + foreach (CultureInfo language in languages) { + languagesListStore.AppendValues (language.DisplayName); } + + packageLanguageComboBox.Active = 0; + } + + static int CompareLanguages (CultureInfo x, CultureInfo y) + { + return string.Compare (x.DisplayName, y.DisplayName, StringComparison.CurrentCulture); } bool ProjectHasMetadata () diff --git a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkProjectNuGetBuildOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkProjectNuGetBuildOptionsPanelWidget.cs index 3645bd12ac..38468f2f14 100644 --- a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkProjectNuGetBuildOptionsPanelWidget.cs +++ b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkProjectNuGetBuildOptionsPanelWidget.cs @@ -44,9 +44,13 @@ namespace MonoDevelop.Packaging.Gui SetupAccessibility (); } - void SetupAccessibility () + void SetupAccessibility (bool includeMissingMetadataLabelText = false) { - packOnBuildButton.SetCommonAccessibilityAttributes ("NugetBuildOptionsPanel.PackOnBuild", "", + string accessibilityLabel = packOnBuildButton.Label; + if (includeMissingMetadataLabelText) { + accessibilityLabel += " " + missingMetadataLabel.Text; + } + packOnBuildButton.SetCommonAccessibilityAttributes ("NugetBuildOptionsPanel.PackOnBuild", accessibilityLabel, GettextCatalog.GetString ("Check to create a NuGet package when building")); } @@ -73,10 +77,15 @@ namespace MonoDevelop.Packaging.Gui void UpdateMissingMetadataLabelVisibility () { - if (packOnBuildButton.Active) { - missingMetadataLabel.Visible = !ProjectHasMetadata; + bool visible = packOnBuildButton.Active && !ProjectHasMetadata; + missingMetadataLabel.Visible = visible; + + // Refresh accessibility information so missing metadata label text is available to Voice Over + // when the check box is selected. + if (visible) { + SetupAccessibility (includeMissingMetadataLabelText: true); } else { - missingMetadataLabel.Visible = false; + SetupAccessibility (); } } diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs index 4d246a48f9..2461c716ba 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs @@ -92,16 +92,24 @@ namespace MonoDevelop.AnalysisCore.Gui diagService.DiagnosticsUpdated -= OnDiagnosticsUpdated; CancelUpdateTimout (); AnalysisOptions.AnalysisEnabled.Changed -= AnalysisOptionsChanged; - foreach (var queue in markers) { - foreach (var marker in queue.Value) - Editor.RemoveMarker (marker); - } + RemoveAllMarkers (); disposed = true; base.Dispose (); } + + void RemoveAllMarkers () + { + foreach (var markerQueue in markers) { + foreach (var marker in markerQueue.Value) { + Editor.RemoveMarker (marker); + } + PutBackCachedList (markerQueue.Value); + } + markers.Clear (); + } bool enabled; - + public bool Enabled { get { return enabled; } set { @@ -247,40 +255,39 @@ namespace MonoDevelop.AnalysisCore.Gui } } + const int MaxCacheSize = 10; + Queue<List<IGenericTextSegmentMarker>> listCache = new Queue<List<IGenericTextSegmentMarker>> (); + + List<IGenericTextSegmentMarker> GetCachedList () + { + if (listCache.Count == 0) + return new List<IGenericTextSegmentMarker> (); + return listCache.Dequeue (); + } + + void PutBackCachedList (List<IGenericTextSegmentMarker> list) + { + list.Clear (); + if (listCache.Count < MaxCacheSize) + listCache.Enqueue (list); + } - class ResultsUpdater + class ResultsUpdater { readonly ResultsEditorExtension ext; readonly CancellationToken cancellationToken; - + //the number of markers at the head of the queue that need tp be removed int oldMarkerIndex; - readonly List<IGenericTextSegmentMarker> oldMarkers; + List<IGenericTextSegmentMarker> oldMarkers; int curResult = 0; IReadOnlyList<Result> results; - private List<IGenericTextSegmentMarker> newMarkers; + List<IGenericTextSegmentMarker> newMarkers; ImmutableArray<QuickTask>.Builder builder; object id; - const int MaxCacheSize = 200; - readonly static Queue<List<IGenericTextSegmentMarker>> listCache = new Queue<List<IGenericTextSegmentMarker>> (); - - static List<IGenericTextSegmentMarker> GetCachedList () - { - if (listCache.Count == 0) - return new List<IGenericTextSegmentMarker> (); - return listCache.Dequeue (); - } - - static void PutBackCachedList (List<IGenericTextSegmentMarker> list) - { - list.Clear (); - if (listCache.Count < MaxCacheSize) - listCache.Enqueue (list); - } - public ResultsUpdater (ResultsEditorExtension ext, IReadOnlyList<Result> results, object resultsId, CancellationToken cancellationToken) { if (ext == null) @@ -292,13 +299,13 @@ namespace MonoDevelop.AnalysisCore.Gui this.cancellationToken = cancellationToken; if (resultsId != null) { - if (!ext.markers.TryGetValue (id, out oldMarkers)) - ext.markers [id] = oldMarkers = GetCachedList (); + ext.markers.TryGetValue (id, out oldMarkers); } builder = ImmutableArray<QuickTask>.Empty.ToBuilder (); this.results = results; - newMarkers = GetCachedList (); + newMarkers = ext.GetCachedList (); + Debug.Assert (newMarkers != null); } public void Update () @@ -341,88 +348,99 @@ namespace MonoDevelop.AnalysisCore.Gui //in order to to block the GUI thread, we batch them in UPDATE_COUNT bool IdleHandler () { - if (cancellationToken.IsCancellationRequested) - return false; - var editor = ext.Editor; - if (editor == null) - return false; - if (id == null) { - foreach (var markerQueue in ext.markers) { - foreach (var marker in markerQueue.Value) { - editor.RemoveMarker (marker); - } - PutBackCachedList (markerQueue.Value); + try { + var editor = ext.Editor; + if (editor == null) + return false; + if (id == null) { + ext.RemoveAllMarkers (); + lock (ext.tasks) + ext.tasks.Clear (); + ext.OnTasksUpdated (EventArgs.Empty); + return false; } - ext.markers.Clear (); - } - if (id == null) { - lock (ext.tasks) - ext.tasks.Clear (); - ext.OnTasksUpdated (EventArgs.Empty); - return false; - } - - //clear the old results out at the same rate we add in the new ones - for (int i = 0; oldMarkerIndex < oldMarkers.Count && i < UPDATE_COUNT; i++) { - if (cancellationToken.IsCancellationRequested) + if (cancellationToken.IsCancellationRequested) { + FinishUpdateRun (); return false; - var oldMarker = oldMarkers [oldMarkerIndex++]; - - if (curResult < results.Count && results [curResult].Equals ((Result)oldMarker.Tag, oldMarker.Offset)) { - oldMarker.Tag = results [curResult]; - newMarkers.Add (oldMarker); - curResult++; - continue; } - editor.RemoveMarker (oldMarker); - } - //add in the new markers - for (int i = 0; i < UPDATE_COUNT; i++) { - if (curResult >= results.Count) { - lock (ext.tasks) - ext.tasks [id] = builder.ToImmutable (); - ext.OnTasksUpdated (EventArgs.Empty); - // remove remaining old markers - while (oldMarkerIndex < oldMarkers.Count) { - editor.RemoveMarker (oldMarkers[oldMarkerIndex]); - oldMarkerIndex++; + //clear the old results out at the same rate we add in the new ones + if (oldMarkers != null) { + for (int i = 0; oldMarkerIndex < oldMarkers.Count && i < UPDATE_COUNT; i++) { + var oldMarker = oldMarkers [oldMarkerIndex++]; + + var oldResult = (Result)oldMarker.Tag; + if (oldResult != null && curResult < results.Count) { + Result currentResult = results [curResult]; + if (currentResult.Equals (oldResult, oldMarker.Offset)) { + oldMarker.Tag = currentResult; + newMarkers.Add (oldMarker); + if (oldResult.QuickTask != null) { + currentResult.QuickTask = oldResult.QuickTask; + builder.Add (currentResult.QuickTask); + } + curResult++; + continue; + } + } + editor.RemoveMarker (oldMarker); } - - PutBackCachedList (ext.markers [id]); - ext.markers [id] = newMarkers; - - return false; } - if (cancellationToken.IsCancellationRequested) - return false; - var currentResult = results [curResult++]; - if (currentResult.InspectionMark != IssueMarker.None) { - int start = currentResult.Region.Start; - int end = currentResult.Region.End; - if (start > end) - continue; - - // In case a diagnostic has a 0 length span, force it to 1. - if (start == end) - end = end + 1; - - var marker = TextMarkerFactory.CreateGenericTextSegmentMarker (editor, GetSegmentMarkerEffect (currentResult.InspectionMark), TextSegment.FromBounds (start, end)); - marker.Tag = currentResult; - marker.IsVisible = currentResult.Underline; - - if (currentResult.InspectionMark != IssueMarker.GrayOut) { - marker.Color = GetColor (editor, currentResult); - marker.IsVisible &= currentResult.Level != DiagnosticSeverity.Hidden; + //add in the new markers + for (int i = 0; i < UPDATE_COUNT; i++) { + if (curResult >= results.Count) { + FinishUpdateRun (); + return false; + } + var currentResult = results [curResult++]; + if (currentResult.InspectionMark != IssueMarker.None) { + int start = currentResult.Region.Start; + int end = currentResult.Region.End; + if (start > end) + continue; + + // In case a diagnostic has a 0 length span, force it to 1. + if (start == end) + end = end + 1; + + var marker = TextMarkerFactory.CreateGenericTextSegmentMarker (editor, GetSegmentMarkerEffect (currentResult.InspectionMark), TextSegment.FromBounds (start, end)); + marker.Tag = currentResult; + marker.IsVisible = currentResult.Underline; + + if (currentResult.InspectionMark != IssueMarker.GrayOut) { + marker.Color = GetColor (editor, currentResult); + marker.IsVisible &= currentResult.Level != DiagnosticSeverity.Hidden; + } + editor.AddMarker (marker); + newMarkers.Add (marker); } - editor.AddMarker (marker); - newMarkers.Add (marker); + builder.Add (currentResult.QuickTask = new QuickTask (currentResult.Message, currentResult.Region.Start, currentResult.Level)); + } + return true; + } catch (Exception ex) { + LoggingService.LogInternalError ("Error while ResutsUpdater.IdleHandler", ex); + return false; + } + } + + void FinishUpdateRun () + { + var editor = ext.Editor; + // remove remaining old markers + if (oldMarkers != null) { + while (oldMarkerIndex < oldMarkers.Count) { + editor.RemoveMarker (oldMarkers [oldMarkerIndex]); + oldMarkerIndex++; } - builder.Add (new QuickTask (currentResult.Message, currentResult.Region.Start, currentResult.Level)); + ext.PutBackCachedList (oldMarkers); + oldMarkers = null; } - return true; + ext.markers [id] = newMarkers; + lock (ext.tasks) + ext.tasks [id] = builder.ToImmutable (); + ext.OnTasksUpdated (EventArgs.Empty); } } diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Result.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Result.cs index ae207cbf0d..3ed4732bc1 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Result.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Result.cs @@ -27,6 +27,7 @@ using System; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; +using MonoDevelop.Ide.Editor.Extension; namespace MonoDevelop.AnalysisCore { @@ -67,6 +68,7 @@ namespace MonoDevelop.AnalysisCore public TextSpan Region { get; private set; } public bool Underline { get; private set; } + public QuickTask QuickTask { get; internal set; } internal bool Equals (Result other, int correctedOffset) { diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs index 69270698f2..fe9805aa9e 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs @@ -353,7 +353,7 @@ namespace MonoDevelop.Refactoring return; } - drawingLayout.SetMarkup (lineResult.TextMarkup); + drawingLayout.SetMarkup (lineResult.TextMarkup ?? ""); drawingLayout.GetPixelSize (out int w, out int h); x = Math.Max (x, w); y += lineHeight; @@ -398,7 +398,7 @@ namespace MonoDevelop.Refactoring { using (var drawingLayout = new Pango.Layout (PangoContext)) { drawingLayout.FontDescription = fontDescription; - drawingLayout.SetMarkup (lineResult.TextMarkup); + drawingLayout.SetMarkup (lineResult.TextMarkup ?? ""); g.Save (); g.Translate (textBorder, y); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/IconMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/IconMargin.cs index a0db793606..cfdd1730b0 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/IconMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/IconMargin.cs @@ -43,16 +43,21 @@ namespace Mono.TextEditor public IconMargin (MonoTextEditor editor) { - this.editor = editor;
-
- editor.Document.MarkerAdded += OnMarkerAdded;
- editor.Document.MarkerRemoved += OnMarkerRemoved; + this.editor = editor; + + if (IdeTheme.AccessibilityEnabled) { + editor.Document.MarkerAdded += OnMarkerAdded;
+ editor.Document.MarkerRemoved += OnMarkerRemoved; + markerToAccessible = new Dictionary<TextLineMarker, AccessibilityMarkerProxy> (); + } } public override void Dispose () {
- editor.Document.MarkerAdded -= OnMarkerAdded;
- editor.Document.MarkerRemoved -= OnMarkerRemoved;
+ if (IdeTheme.AccessibilityEnabled) { + editor.Document.MarkerAdded -= OnMarkerAdded; + editor.Document.MarkerRemoved -= OnMarkerRemoved; + }
if (markerToAccessible != null) {
foreach (var proxy in markerToAccessible.Values) {
@@ -187,44 +192,30 @@ namespace Mono.TextEditor } } - Dictionary<TextLineMarker, AccessibilityMarkerProxy> markerToAccessible = null;
+ Dictionary<TextLineMarker, AccessibilityMarkerProxy> markerToAccessible; +
void OnMarkerAdded (object sender, TextMarkerEvent e)
{ - if (!IdeTheme.AccessibilityEnabled) { - return; + lock (markerToAccessible) { + var proxy = new AccessibilityMarkerProxy (e.TextMarker, editor, this); + Accessible.AddAccessibleChild (proxy.Accessible); + markerToAccessible [e.TextMarker] = proxy; } - if (markerToAccessible == null) {
- markerToAccessible = new Dictionary<TextLineMarker, AccessibilityMarkerProxy> ();
- }
-
- var proxy = new AccessibilityMarkerProxy (e.TextMarker, editor, this);
- Accessible.AddAccessibleChild (proxy.Accessible);
-
- markerToAccessible [e.TextMarker] = proxy; - if (focusMarkers != null) { UpdateMarkers (); - }
+ } }
void OnMarkerRemoved (object sender, TextMarkerEvent e)
{ - if (!IdeTheme.AccessibilityEnabled) { - return; + lock (markerToAccessible) { + if (!markerToAccessible.TryGetValue (e.TextMarker, out var proxy)) { + return; + } + Accessible.RemoveAccessibleChild (proxy.Accessible); + markerToAccessible.Remove (e.TextMarker); } -
- if (markerToAccessible == null) {
- return;
- }
-
- var proxy = markerToAccessible [e.TextMarker];
- if (proxy == null) {
- throw new Exception ("No accessible found for marker");
- }
-
- Accessible.RemoveAccessibleChild (proxy.Accessible);
- markerToAccessible.Remove (e.TextMarker); if (focusMarkers != null) { UpdateMarkers (); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index 20f8c18b96..6cb5586a22 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -670,18 +670,23 @@ namespace Mono.TextEditor #if MAC try { lineHeight = System.Math.Ceiling (0.5 + OSXEditor.GetLineHeight(font.ToString ())); + if (lineHeight < 0) + lineHeight = GetLineHeight (metrics); } catch (Exception e) { LoggingService.LogError ("Error while getting the macOS font metrics for " + font, e); - lineHeight = System.Math.Ceiling (0.5 + (metrics.Ascent + metrics.Descent) / Pango.Scale.PangoScale); + lineHeight = GetLineHeight (metrics); } #else - lineHeight = System.Math.Ceiling(0.5 + (metrics.Ascent + metrics.Descent) / Pango.Scale.PangoScale); + lineHeight = GetLineHeight (metrics); #endif underlinePosition = metrics.UnderlinePosition; underLineThickness = metrics.UnderlineThickness; charWidth = metrics.ApproximateCharWidth / Pango.Scale.PangoScale; } } + + static double GetLineHeight (Pango.FontMetrics metrics) => System.Math.Ceiling (0.5 + (metrics.Ascent + metrics.Descent) / Pango.Scale.PangoScale); + public override void Dispose () { CancelCodeSegmentTooltip (); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ClipboardRingService.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ClipboardRingService.cs index 8b7b82c1c5..7267c06042 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ClipboardRingService.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ClipboardRingService.cs @@ -31,6 +31,7 @@ using MonoDevelop.Core; using MonoDevelop.DesignerSupport.Toolbox; using MonoDevelop.Ide; using MonoDevelop.Ide.Gui; +using System.Linq; namespace MonoDevelop.SourceEditor { @@ -102,6 +103,8 @@ namespace MonoDevelop.SourceEditor return clipboardRing; } + internal static bool DeleteItem (ItemToolboxNode node) => clipboardRing.Remove (node as ClipboardToolboxNode); + class ClipboardToolboxNode : ItemToolboxNode, ITextToolboxNode, ICustomTooltipToolboxNode { static readonly ToolboxItemFilterAttribute filterAtt = new ToolboxItemFilterAttribute ("text/plain", ToolboxItemFilterType.Allow); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs index 844c92afd5..020f46d3bd 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs @@ -66,7 +66,7 @@ using System.Collections.Immutable; namespace MonoDevelop.SourceEditor { partial class SourceEditorView : ViewContent, IBookmarkBuffer, IClipboardHandler, ITextFile, - ICompletionWidget2, ISplittable, IFoldable, IToolboxDynamicProvider, + ICompletionWidget2, ISplittable, IFoldable, IToolboxDynamicProvider, IToolboxDynamicProviderDeleteSupport, ICustomFilteringToolboxConsumer, IZoomable, ITextEditorResolver, ITextEditorDataProvider, ICodeTemplateHandler, ICodeTemplateContextProvider, IPrintable, ITextEditorImpl, ITextMarkerFactory, IUndoHandler @@ -3091,14 +3091,20 @@ namespace MonoDevelop.SourceEditor string ITextEditorImpl.GetMarkup (int offset, int length, MarkupOptions options) { + return GetMarkupAsync (offset, length, options, default).WaitAndGetResult (default); + } + + public async Task<string> GetMarkupAsync (int offset, int length, MarkupOptions options, CancellationToken cancellationToken = default) + { + Runtime.AssertMainThread (); var data = TextEditor.GetTextEditorData (); switch (options.MarkupFormat) { case MarkupFormat.Pango: - return data.GetMarkup (offset, length, false, replaceTabs: false, fitIdeStyle: options.FitIdeStyle); + return await data.GetMarkupAsync (offset, length, false, replaceTabs: false, fitIdeStyle: options.FitIdeStyle, cancellationToken: cancellationToken); case MarkupFormat.Html: - return HtmlWriter.GenerateHtml (ClipboardColoredText.GetChunks (data, new TextSegment (offset, length)).WaitAndGetResult (default (System.Threading.CancellationToken)), data.ColorStyle, data.Options); + return HtmlWriter.GenerateHtml (await ClipboardColoredText.GetChunks (data, new TextSegment (offset, length), cancellationToken), data.ColorStyle, data.Options); case MarkupFormat.RichText: - return RtfWriter.GenerateRtf (ClipboardColoredText.GetChunks (data, new TextSegment (offset, length)).WaitAndGetResult (default (System.Threading.CancellationToken)), data.ColorStyle, data.Options); + return RtfWriter.GenerateRtf (await ClipboardColoredText.GetChunks (data, new TextSegment (offset, length), cancellationToken), data.ColorStyle, data.Options); default: throw new ArgumentOutOfRangeException (); } @@ -3393,6 +3399,10 @@ namespace MonoDevelop.SourceEditor return TextEditor.GetLineHeight (line); } + public bool DeleteDynamicItem (ItemToolboxNode node) => ClipboardRingService.DeleteItem (node); + + public bool CanDeleteDynamicItem (ItemToolboxNode node) => ClipboardRingService.GetToolboxItems ().Contains (node); + public bool HasFocus { get { return this.TextEditor.HasFocus; diff --git a/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/ExternalTestRunner.cs b/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/ExternalTestRunner.cs index 51fa5342d2..2cbf788fe0 100644 --- a/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/ExternalTestRunner.cs +++ b/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/ExternalTestRunner.cs @@ -48,6 +48,8 @@ namespace MonoDevelop.UnitTesting.NUnit.External IRemoteEventListener listener; readonly string assemblyDirectory; + public ProcessExecutionArchitecture ProcessExecutionArchitecture { get; set; } + public ExternalTestRunner () { } @@ -61,6 +63,7 @@ namespace MonoDevelop.UnitTesting.NUnit.External { var exePath = Path.Combine (Path.GetDirectoryName (GetType ().Assembly.Location), version.ToString (), "NUnitRunner.exe"); connection = new RemoteProcessConnection (exePath, assemblyDirectory, executionHandler, console, Runtime.MainSynchronizationContext); + connection.ProcessExecutionArchitecture = ProcessExecutionArchitecture; connection.AddListener (this); return connection.Connect (); } diff --git a/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/NUnitAssemblyTestSuite.cs b/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/NUnitAssemblyTestSuite.cs index b75a993743..5b3e57bbed 100644 --- a/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/NUnitAssemblyTestSuite.cs +++ b/main/src/addins/MonoDevelop.UnitTesting.NUnit/MonoDevelop.UnitTesting.NUnit/NUnitAssemblyTestSuite.cs @@ -44,6 +44,7 @@ using System.Xml.Linq; using System.Linq; using System.Globalization; using System.Threading.Tasks; +using MonoDevelop.Core.Assemblies; namespace MonoDevelop.UnitTesting.NUnit { @@ -333,6 +334,7 @@ namespace MonoDevelop.UnitTesting.NUnit try { if (File.Exists (ld.Path)) { runner = new ExternalTestRunner (Path.GetDirectoryName (ld.Path)); + runner.ProcessExecutionArchitecture = AssemblyUtilities.GetProcessExecutionArchitectureForAssembly (ld.Path); runner.Connect (ld.NUnitVersion).Wait (); var supportAssemblies = new List<string> (ld.SupportAssemblies.Result); ld.Info = runner.GetTestInfo (ld.Path, supportAssemblies).Result; @@ -398,6 +400,7 @@ namespace MonoDevelop.UnitTesting.NUnit OperationConsoleFactory.CreateConsoleOptions.Default.WithTitle (GettextCatalog.GetString ("Unit Tests"))); ExternalTestRunner runner = new ExternalTestRunner (Path.GetDirectoryName (AssemblyPath)); + runner.ProcessExecutionArchitecture = AssemblyUtilities.GetProcessExecutionArchitectureForAssembly (AssemblyPath); runner.Connect (NUnitVersion, testContext.ExecutionContext.ExecutionHandler, console).Wait (); LocalTestMonitor localMonitor = new LocalTestMonitor (testContext, test, suiteName, testName != null); |