From 2c1c16e2607b8dcc88172bc9ec9487e015af5b0f Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Mon, 3 Jun 2013 01:30:51 +0200 Subject: [PATCH] Reintroduced "insert constructor snippet" feature. --- .../CSharpBinding/Project/CSharpBinding.addin | 6 + .../Project/CSharpBinding.csproj | 8 + .../Project/Src/CodeManipulation.cs | 17 +- .../AbstractInlineRefactorDialog.cs | 161 +++++++++++ .../InlineRefactorSnippetElement.cs | 35 +++ .../Src/Refactoring/InsertCtorDialog.xaml | 57 ++++ .../Src/Refactoring/InsertCtorDialog.xaml.cs | 273 ++++++++++++++++++ .../InsertCtorSnippetRefactoring.cs | 93 ++++++ .../Src/Refactoring/PropertyOrFieldWrapper.cs | 121 ++++++++ 9 files changed, 765 insertions(+), 6 deletions(-) create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InlineRefactorSnippetElement.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorSnippetRefactoring.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/PropertyOrFieldWrapper.cs diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin index a81b51169a..016735c4c1 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin @@ -155,6 +155,12 @@ class="CSharpBinding.Refactoring.SearchForIssuesCommand"/> + + + + + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index 883b300713..cd4338d5e3 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -76,8 +76,14 @@ + + + + InsertCtorDialog.xaml + + IssueOptions.xaml @@ -88,6 +94,7 @@ + @@ -183,6 +190,7 @@ + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs index b33ee33e57..40ed4fcd26 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CodeManipulation.cs @@ -3,16 +3,21 @@ using System; using System.Collections.Generic; using System.Linq; + /* +using System.Windows.Input; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.Core; using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.PatternMatching; +//using ICSharpCode.NRefactory.Ast; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Refactoring; -using Ast = ICSharpCode.NRefactory.Ast; +//using Ast = ICSharpCode.NRefactory.Ast; namespace CSharpBinding { @@ -100,8 +105,8 @@ namespace CSharpBinding class Selection { - public Location Start { get; set; } - public Location End { get; set; } + public TextLocation Start { get; set; } + public TextLocation End { get; set; } } void CodeManipulationSelectionChanged(object sender, EventArgs e) @@ -163,7 +168,7 @@ namespace CSharpBinding string currentNodeText = editor.Document.GetText(statementSelection.Start, statementSelection.End); SwapText(editor.Document, statementSelection.Start, statementSelection.End, swapSibling.StartLocation, swapSibling.EndLocation); // Move caret to the start of moved statement - Location upperLocation = new Location[] {statementSelection.Start, swapSibling.StartLocation}.Min(); + TextLocation upperLocation = new TextLocation[] {statementSelection.Start, swapSibling.StartLocation}.Min(); if (direction == MoveStatementDirection.Up) editor.Caret.Position = upperLocation; else { @@ -454,4 +459,4 @@ namespace CSharpBinding } } } -*/ +*/ \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs new file mode 100644 index 0000000000..6140d3af60 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/AbstractInlineRefactorDialog.cs @@ -0,0 +1,161 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Threading; + +using ICSharpCode.AvalonEdit.Snippets; +using ICSharpCode.Core.Presentation; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Parser; +using CSharpBinding.Refactoring; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Editor; + +namespace CSharpBinding.Refactoring +{ + public abstract class AbstractInlineRefactorDialog : GroupBox, IOptionBindingContainer, IActiveElement + { + protected ITextAnchor anchor; + protected ITextAnchor insertionEndAnchor; + protected ITextEditor editor; + + protected SDRefactoringContext refactoringContext; + protected InsertionContext insertionContext; + + public IInlineUIElement Element { get; set; } + + protected AbstractInlineRefactorDialog(InsertionContext context, ITextEditor editor, ITextAnchor anchor) + { + if (context == null) + throw new ArgumentNullException("context"); + + this.anchor = insertionEndAnchor = anchor; + this.editor = editor; + this.insertionContext = context; + this.refactoringContext = SDRefactoringContext.Create(editor, CancellationToken.None); + + this.Background = SystemColors.ControlBrush; + } + + protected virtual void FocusFirstElement() + { + Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(delegate { this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); })); + } + + protected abstract string GenerateCode(IUnresolvedTypeDefinition currentClass); + + protected virtual void OKButtonClick(object sender, RoutedEventArgs e) + { + ParseInformation parseInfo = SD.ParserService.GetCachedParseInformation(editor.FileName); + + if (optionBindings != null) { + foreach (OptionBinding binding in optionBindings) + binding.Save(); + } + + if (parseInfo != null) { + IUnresolvedTypeDefinition current = parseInfo.UnresolvedFile.GetInnermostTypeDefinition(anchor.Line, anchor.Column); + + using (editor.Document.OpenUndoGroup()) { + // GenerateCode could modify the document. + // So read anchor.Offset after code generation. + GenerateCode(current); + } + } + + Deactivate(); + } + + protected virtual void CancelButtonClick(object sender, RoutedEventArgs e) + { + Deactivate(); + } + + List optionBindings; + + public void AddBinding(OptionBinding binding) + { + if (optionBindings == null) + optionBindings = new List(); + + optionBindings.Add(binding); + } + + protected AstType ConvertType(IType type) + { + return refactoringContext.CreateShortType(type); + } + + bool IActiveElement.IsEditable { + get { return false; } + } + + ISegment IActiveElement.Segment { + get { return null; } + } + + void IActiveElement.OnInsertionCompleted() + { + OnInsertionCompleted(); + } + + protected virtual void OnInsertionCompleted() + { + FocusFirstElement(); + } + + void IActiveElement.Deactivate(SnippetEventArgs e) + { + if (e.Reason == DeactivateReason.Deleted) { + Deactivate(); + return; + } + + if (e.Reason == DeactivateReason.ReturnPressed) + OKButtonClick(null, null); + + if (e.Reason == DeactivateReason.EscapePressed) + CancelButtonClick(null, null); + + Deactivate(); + } + + bool deactivated; + + void Deactivate() + { + if (Element == null) + throw new InvalidOperationException("no IInlineUIElement set!"); + if (deactivated) + return; + + deactivated = true; + Element.Remove(); + + insertionContext.Deactivate(null); + } + + protected Key? GetAccessKeyFromButton(ContentControl control) + { + if (control == null) + return null; + string text = control.Content as string; + if (text == null) + return null; + int index = text.IndexOf('_'); + if (index < 0 || index > text.Length - 2) + return null; + char ch = text[index + 1]; + // works only for letter keys! + return (Key)new KeyConverter().ConvertFrom(ch.ToString()); + } + } +} diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InlineRefactorSnippetElement.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InlineRefactorSnippetElement.cs new file mode 100644 index 0000000000..9bdf90d8b3 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InlineRefactorSnippetElement.cs @@ -0,0 +1,35 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Linq; +using System.Windows.Documents; + +using ICSharpCode.AvalonEdit.Snippets; + +namespace CSharpBinding.Refactoring +{ + class InlineRefactorSnippetElement : SnippetElement + { + Func createDialog; + string previewText; + + public InlineRefactorSnippetElement(Func createDialog, string previewText) + { + this.createDialog = createDialog; + this.previewText = previewText; + } + + public override void Insert(InsertionContext context) + { + AbstractInlineRefactorDialog dialog = createDialog(context); + if (dialog != null) + context.RegisterActiveElement(this, dialog); + } + + public override Inline ToTextRun() + { + return new Italic() { Inlines = { previewText } }; + } + } +} diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml new file mode 100644 index 0000000000..a89ebde120 --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml @@ -0,0 +1,57 @@ + + + +