Browse Source

Moved

Rename, Move class to file, Rename file, Extract interface class context menu items from SharpDevelop to SharpRefactoring.addin.

Added comments to MenuBuilders about Addin tree paths where they are registered, for better clarity on how the menu builders work.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6126 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Martin Koníček 15 years ago
parent
commit
86fec631cd
  1. 4
      AddIns/ICSharpCode.SharpDevelop.addin
  2. 4
      src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.addin
  3. 3
      src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.csproj
  4. 115
      src/AddIns/Misc/SharpRefactoring/Project/Src/ClassRefactoringSubmenuBuilder.cs
  5. 46
      src/AddIns/Misc/SharpRefactoring/Project/Src/RefactoringHelpers.cs
  6. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  7. 208
      src/Main/Base/Project/Src/Editor/Commands/ClassBookmarkSubmenuBuilder.cs
  8. 5
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs

4
AddIns/ICSharpCode.SharpDevelop.addin

@ -1726,7 +1726,7 @@
</Path> </Path>
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu"> <Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu">
<MenuItem id = "MenuBuilder" type="Builder" class = "ICSharpCode.SharpDevelop.Editor.Commands.ClassBookmarkMenuBuilder" /> <MenuItem id = "MenuBuilder" type="Builder" class = "ICSharpCode.SharpDevelop.Editor.Commands.ClassBookmarkSubmenuBuilder" />
</Path> </Path>
<Path name = "/SharpDevelop/Pads/ClassBrowser/MemberContextMenu"> <Path name = "/SharpDevelop/Pads/ClassBrowser/MemberContextMenu">
@ -1734,7 +1734,7 @@
</Path> </Path>
<Path name = "/SharpDevelop/Pads/ClassBrowser/ClassContextMenu"> <Path name = "/SharpDevelop/Pads/ClassBrowser/ClassContextMenu">
<MenuItem id = "MenuBuilder" type="Builder" class = "ICSharpCode.SharpDevelop.Editor.Commands.ClassBookmarkMenuBuilder" /> <MenuItem id = "MenuBuilder" type="Builder" class = "ICSharpCode.SharpDevelop.Editor.Commands.ClassBookmarkSubmenuBuilder" />
</Path> </Path>
<Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/Common"> <Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/Refactoring/Common">

4
src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.addin

@ -18,14 +18,14 @@
<Path name="/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu"> <Path name="/SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu">
<MenuItem id="classCodeGenerators" <MenuItem id="classCodeGenerators"
type="Builder" type="Builder"
class="SharpRefactoring.ClassCodeGeneratorMenuBuilder" class="SharpRefactoring.ClassRefactoringSubmenuBuilder"
insertbefore="MenuBuilder" /> insertbefore="MenuBuilder" />
</Path> </Path>
<Path name="/SharpDevelop/Pads/ClassBrowser/ClassContextMenu"> <Path name="/SharpDevelop/Pads/ClassBrowser/ClassContextMenu">
<MenuItem id="classCodeGenerators" <MenuItem id="classCodeGenerators"
type="Builder" type="Builder"
class="SharpRefactoring.ClassCodeGeneratorMenuBuilder" class="SharpRefactoring.ClassRefactoringSubmenuBuilder"
insertbefore="MenuBuilder" /> insertbefore="MenuBuilder" />
</Path> </Path>

3
src/AddIns/Misc/SharpRefactoring/Project/SharpRefactoring.csproj

@ -69,7 +69,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<Compile Include="Configuration\AssemblyInfo.cs" /> <Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="Src\ClassCodeGeneratorMenuBuilder.cs" /> <Compile Include="Src\ClassRefactoringSubmenuBuilder.cs" />
<Compile Include="Src\CSharpMethodExtractor.cs" /> <Compile Include="Src\CSharpMethodExtractor.cs" />
<Compile Include="Src\Extensions.cs" /> <Compile Include="Src\Extensions.cs" />
<Compile Include="Src\ExtractMethodCommand.cs" /> <Compile Include="Src\ExtractMethodCommand.cs" />
@ -106,6 +106,7 @@
<Compile Include="Src\OverrideToStringMethodRefactoring.cs" /> <Compile Include="Src\OverrideToStringMethodRefactoring.cs" />
<Compile Include="Src\ParameterCheckRefactoringMenuBuilder.cs" /> <Compile Include="Src\ParameterCheckRefactoringMenuBuilder.cs" />
<Compile Include="Src\Options.cs" /> <Compile Include="Src\Options.cs" />
<Compile Include="Src\RefactoringHelpers.cs" />
<Compile Include="Src\ResolveAttribute.cs" /> <Compile Include="Src\ResolveAttribute.cs" />
<Compile Include="Src\ResolveExtensionMethod.cs" /> <Compile Include="Src\ResolveExtensionMethod.cs" />
<Compile Include="Src\SwitchBodySnippetElement.cs" /> <Compile Include="Src\SwitchBodySnippetElement.cs" />

115
src/AddIns/Misc/SharpRefactoring/Project/Src/ClassCodeGeneratorMenuBuilder.cs → src/AddIns/Misc/SharpRefactoring/Project/Src/ClassRefactoringSubmenuBuilder.cs

@ -6,8 +6,9 @@
// </file> // </file>
using System; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using ICSharpCode.Core; using ICSharpCode.Core;
@ -19,12 +20,22 @@ using ICSharpCode.SharpDevelop.Bookmarks;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.Refactoring; using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Commands;
using ICSharpCode.SharpDevelop.Gui.ClassBrowser; using ICSharpCode.SharpDevelop.Gui.ClassBrowser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Refactoring; using ICSharpCode.SharpDevelop.Refactoring;
namespace SharpRefactoring namespace SharpRefactoring
{ {
public class ClassCodeGeneratorMenuBuilder : ISubmenuBuilder, IMenuItemBuilder /// <summary>
/// Generates items the class submenu.
/// Paths:
/// /SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu, id=classCodeGenerators
/// /SharpDevelop/Pads/ClassBrowser/ClassContextMenu, id=classCodeGenerators
///
/// This builder generates items to the same submenu as <see cref="ICSharpCode.SharpDevelop.Editor.Commands.ClassBookmarkSubmenuBuilder."></see>.
/// </summary>
public class ClassRefactoringSubmenuBuilder : ISubmenuBuilder, IMenuItemBuilder
{ {
public System.Collections.ICollection BuildItems(Codon codon, object owner) public System.Collections.ICollection BuildItems(Codon codon, object owner)
{ {
@ -35,28 +46,92 @@ namespace SharpRefactoring
{ {
List<ToolStripItem> resultItems = new List<ToolStripItem>(); List<ToolStripItem> resultItems = new List<ToolStripItem>();
IClass c; IClass c = ClassBookmarkSubmenuBuilder.GetClass(owner);
ClassNode classNode = owner as ClassNode; if (c == null) {
if (classNode != null) { return new ToolStripMenuItem[0];
c = classNode.Class;
} else {
ClassBookmark bookmark = (ClassBookmark)owner;
c = bookmark.Class;
} }
LanguageProperties language = c.ProjectContent.Language; LanguageProperties language = c.ProjectContent.Language;
if (language != LanguageProperties.CSharp)
return resultItems.ToArray();
AddImplementAbstractClassCommands(c, resultItems); if (language == LanguageProperties.CSharp) {
AddImplementAbstractClassCommands(c, resultItems);
}
if (c.BaseTypes.Count > 0 && c.ClassType != ClassType.Interface && !FindReferencesAndRenameHelper.IsReadOnly(c)) { if (c.BaseTypes.Count > 0 && c.ClassType != ClassType.Interface && !FindReferencesAndRenameHelper.IsReadOnly(c)) {
AddImplementInterfaceCommands(c, resultItems); AddImplementInterfaceCommands(c, resultItems);
} }
if (!FindReferencesAndRenameHelper.IsReadOnly(c)) {
AddCorrectClassFileNameCommands(c, resultItems);
AddRenameCommand(c, resultItems);
if (language.RefactoringProvider.SupportsExtractInterface) {
AddExtractInterfaceCommand(c, resultItems);
}
}
return resultItems.ToArray(); return resultItems.ToArray();
} }
void AddRenameCommand(IClass c, List<ToolStripItem> resultItems)
{
var cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename);
cmd.ShortcutKeys = MenuCommand.ParseShortcut("Control|R");
cmd.Tag = c;
resultItems.Add(cmd);
}
void AddExtractInterfaceCommand(IClass c, List<ToolStripItem> resultItems)
{
var cmd = new MenuCommand("${res:SharpDevelop.Refactoring.ExtractInterfaceCommand}", ExtractInterface);
cmd.Tag = c;
resultItems.Add(cmd);
}
void AddCorrectClassFileNameCommands(IClass c, List<ToolStripItem> resultItems)
{
if (c.DeclaringType == null &&
!c.BodyRegion.IsEmpty &&
!c.Name.Equals(Path.GetFileNameWithoutExtension(c.CompilationUnit.FileName),
StringComparison.OrdinalIgnoreCase))
{
// File name does not match class name
string correctFileName = Path.Combine(Path.GetDirectoryName(c.CompilationUnit.FileName),
c.Name + Path.GetExtension(c.CompilationUnit.FileName));
if (FileUtility.IsValidPath(correctFileName)
&& Path.IsPathRooted(correctFileName)
&& !File.Exists(correctFileName))
{
if (c.CompilationUnit.Classes.Count == 1) {
// Rename file to ##
var cmd = new MenuCommand(
StringParser.Parse("${res:SharpDevelop.Refactoring.RenameFileTo}",
new string[,] {{ "FileName", Path.GetFileName(correctFileName) }}),
delegate {
IProject p = (IProject)c.ProjectContent.Project;
RefactoringHelpers.RenameFile(p, c.CompilationUnit.FileName, correctFileName);
if (p != null) {
p.Save();
}
});
resultItems.Add(cmd);
} else {
var refactoringProvider = c.ProjectContent.Language.RefactoringProvider;
if (refactoringProvider.SupportsCreateNewFileLikeExisting && refactoringProvider.SupportsGetFullCodeRangeForType) {
// Move class to file ##
var cmd = new MenuCommand(
StringParser.Parse("${res:SharpDevelop.Refactoring.MoveClassToFile}",
new string[,] {{ "FileName", Path.GetFileName(correctFileName) }}),
delegate {
FindReferencesAndRenameHelper.MoveClassToFile(c, correctFileName);
});
resultItems.Add(cmd);
}
}
}
}
}
void AddImplementInterfaceCommands(IClass c, List<ToolStripItem> list) void AddImplementInterfaceCommands(IClass c, List<ToolStripItem> list)
{ {
CodeGenerator codeGen = c.ProjectContent.Language.CodeGenerator; CodeGenerator codeGen = c.ProjectContent.Language.CodeGenerator;
@ -129,7 +204,7 @@ namespace SharpRefactoring
} }
} }
#region Code generation #region Implementation
void ImplementAbstractClass(IDocument document, IClass target, IReturnType abstractClass) void ImplementAbstractClass(IDocument document, IClass target, IReturnType abstractClass)
{ {
CodeGenerator generator = target.ProjectContent.Language.CodeGenerator; CodeGenerator generator = target.ProjectContent.Language.CodeGenerator;
@ -142,6 +217,18 @@ namespace SharpRefactoring
generator.InsertCodeAtEnd(target.BodyRegion, doc, generator.GetOverridingMethod(member, context)); generator.InsertCodeAtEnd(target.BodyRegion, doc, generator.GetOverridingMethod(member, context));
} }
} }
void Rename(object sender, EventArgs e)
{
MenuCommand item = (MenuCommand)sender;
FindReferencesAndRenameHelper.RenameClass((IClass)item.Tag);
}
void ExtractInterface(object sender, EventArgs e)
{
MenuCommand item = (MenuCommand)sender;
FindReferencesAndRenameHelper.ExtractInterface((IClass)item.Tag);
}
#endregion #endregion
#region Helpers #region Helpers

46
src/AddIns/Misc/SharpRefactoring/Project/Src/RefactoringHelpers.cs

@ -0,0 +1,46 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Martin Konicek" email="martin.konicek@gmail.com"/>
// <version>$Revision: $</version>
// </file>
using System;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
namespace SharpRefactoring
{
public class RefactoringHelpers
{
/// <summary>
/// Renames file as well as files it is dependent upon.
/// </summary>
public static void RenameFile(IProject p, string oldFileName, string newFileName)
{
FileService.RenameFile(oldFileName, newFileName, false);
if (p != null) {
string oldPrefix = Path.GetFileNameWithoutExtension(oldFileName) + ".";
string newPrefix = Path.GetFileNameWithoutExtension(newFileName) + ".";
foreach (ProjectItem item in p.Items) {
FileProjectItem fileItem = item as FileProjectItem;
if (fileItem == null)
continue;
string dependentUpon = fileItem.DependentUpon;
if (string.IsNullOrEmpty(dependentUpon))
continue;
string directory = Path.GetDirectoryName(fileItem.FileName);
dependentUpon = Path.Combine(directory, dependentUpon);
if (FileUtility.IsEqualFileName(dependentUpon, oldFileName)) {
fileItem.DependentUpon = FileUtility.GetRelativePath(directory, newFileName);
string fileName = Path.GetFileName(fileItem.FileName);
if (fileName.StartsWith(oldPrefix)) {
RenameFile(p, fileItem.FileName, Path.Combine(directory, newPrefix + fileName.Substring(oldPrefix.Length)));
}
}
}
}
}
}
}

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

@ -97,7 +97,7 @@
</Compile> </Compile>
<Compile Include="Src\Editor\CodeCompletion\ICompletionItemHandler.cs" /> <Compile Include="Src\Editor\CodeCompletion\ICompletionItemHandler.cs" />
<Compile Include="Src\Editor\CodeCompletion\NRefactoryCompletionItemList.cs" /> <Compile Include="Src\Editor\CodeCompletion\NRefactoryCompletionItemList.cs" />
<Compile Include="Src\Editor\Commands\ClassBookmarkMenuBuilder.cs" /> <Compile Include="Src\Editor\Commands\ClassBookmarkSubmenuBuilder.cs" />
<Compile Include="Src\Editor\Commands\ClassMemberMenuBuilder.cs" /> <Compile Include="Src\Editor\Commands\ClassMemberMenuBuilder.cs" />
<Compile Include="Src\Editor\Commands\FindBaseClasses.cs" /> <Compile Include="Src\Editor\Commands\FindBaseClasses.cs" />
<Compile Include="Src\Editor\Commands\FindDerivedClassesOrOverrides.cs" /> <Compile Include="Src\Editor\Commands\FindDerivedClassesOrOverrides.cs" />

208
src/Main/Base/Project/Src/Editor/Commands/ClassBookmarkMenuBuilder.cs → src/Main/Base/Project/Src/Editor/Commands/ClassBookmarkSubmenuBuilder.cs

@ -27,62 +27,18 @@ using ICSharpCode.SharpDevelop.Refactoring;
namespace ICSharpCode.SharpDevelop.Editor.Commands namespace ICSharpCode.SharpDevelop.Editor.Commands
{ {
/// <summary> /// <summary>
/// Build context menu for class members in the text editor. /// Build context submenu for class members in the text editor.
/// Paths:
/// /SharpDevelop/ViewContent/DefaultTextEditor/ClassBookmarkContextMenu, id=MenuBuilder
/// /SharpDevelop/Pads/ClassBrowser/ClassContextMenu, id=MenuBuilder
/// </summary> /// </summary>
public class ClassBookmarkMenuBuilder : ISubmenuBuilder, IMenuItemBuilder public class ClassBookmarkSubmenuBuilder : ISubmenuBuilder, IMenuItemBuilder
{ {
public System.Collections.ICollection BuildItems(Codon codon, object owner) public System.Collections.ICollection BuildItems(Codon codon, object owner)
{ {
return BuildSubmenu(codon, owner).TranslateToWpf(); return BuildSubmenu(codon, owner).TranslateToWpf();
} }
/// <summary>
/// Gets a specific part of the compound class.
/// </summary>
static IClass GetPart(IClass possibleCompound, string fileName)
{
CompoundClass compound = possibleCompound as CompoundClass;
if (compound == null)
return possibleCompound;
IList<IClass> parts = compound.Parts;
if (!string.IsNullOrEmpty(fileName)) {
// get the part with the requested file name
foreach (IClass part in parts) {
if (FileUtility.IsEqualFileName(fileName, part.CompilationUnit.FileName))
return part;
}
}
// Fallback: get the part with the shortest file name.
// This should prefer non-designer files over designer files.
IClass preferredClass = parts[0];
for (int i = 1; i < parts.Count; i++) {
if (IsShorterFileName(parts[i].CompilationUnit.FileName, preferredClass.CompilationUnit.FileName))
preferredClass = parts[i];
}
return preferredClass;
}
static bool IsShorterFileName(string a, string b)
{
// Fix forum-17295: compilation unit's file name might be null: prefer the non-null file
if (a == null)
return false;
if (b == null)
return true;
return a.Length < b.Length;
}
static IClass GetCurrentPart(IClass possibleCompound)
{
IViewContent viewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
if (viewContent != null)
return GetPart(possibleCompound, viewContent.PrimaryFileName);
else
return GetPart(possibleCompound, null);
}
public ToolStripItem[] BuildSubmenu(Codon codon, object owner) public ToolStripItem[] BuildSubmenu(Codon codon, object owner)
{ {
MenuCommand cmd; MenuCommand cmd;
@ -106,58 +62,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
List<ToolStripItem> list = new List<ToolStripItem>(); List<ToolStripItem> list = new List<ToolStripItem>();
// refactoring actions
if (!FindReferencesAndRenameHelper.IsReadOnly(c)) {
if (c.DeclaringType == null &&
!c.BodyRegion.IsEmpty &&
!c.Name.Equals(Path.GetFileNameWithoutExtension(c.CompilationUnit.FileName),
StringComparison.OrdinalIgnoreCase))
{
// File name does not match class name
string correctFileName = Path.Combine(Path.GetDirectoryName(c.CompilationUnit.FileName),
c.Name + Path.GetExtension(c.CompilationUnit.FileName));
if (FileUtility.IsValidPath(correctFileName)
&& Path.IsPathRooted(correctFileName)
&& !File.Exists(correctFileName))
{
if (c.CompilationUnit.Classes.Count == 1) {
// Rename file to ##
cmd = new MenuCommand(
StringParser.Parse("${res:SharpDevelop.Refactoring.RenameFileTo}",
new string[,] {{ "FileName", Path.GetFileName(correctFileName) }}),
delegate {
IProject p = (IProject)c.ProjectContent.Project;
RenameFile(p, c.CompilationUnit.FileName, correctFileName);
if (p != null) {
p.Save();
}
});
list.Add(cmd);
} else if (language.RefactoringProvider.SupportsCreateNewFileLikeExisting && language.RefactoringProvider.SupportsGetFullCodeRangeForType) {
// Move class to file ##
cmd = new MenuCommand(
StringParser.Parse("${res:SharpDevelop.Refactoring.MoveClassToFile}",
new string[,] {{ "FileName", Path.GetFileName(correctFileName) }}),
delegate {
FindReferencesAndRenameHelper.MoveClassToFile(c, correctFileName);
});
list.Add(cmd);
}
}
}
cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename);
cmd.ShortcutKeys = MenuCommand.ParseShortcut("Control|R");
cmd.Tag = c;
list.Add(cmd);
if (language.RefactoringProvider.SupportsExtractInterface) {
cmd = new MenuCommand("${res:SharpDevelop.Refactoring.ExtractInterfaceCommand}", ExtractInterface);
cmd.Tag = c;
list.Add(cmd);
}
}
// navigation actions // navigation actions
if (c.BaseTypes.Count > 0) { if (c.BaseTypes.Count > 0) {
list.Add(new MenuSeparator()); list.Add(new MenuSeparator());
@ -182,38 +86,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
return list.ToArray(); return list.ToArray();
} }
static void RenameFile(IProject p, string oldFileName, string newFileName)
{
FileService.RenameFile(oldFileName, newFileName, false);
if (p != null) {
string oldPrefix = Path.GetFileNameWithoutExtension(oldFileName) + ".";
string newPrefix = Path.GetFileNameWithoutExtension(newFileName) + ".";
foreach (ProjectItem item in p.Items) {
FileProjectItem fileItem = item as FileProjectItem;
if (fileItem == null)
continue;
string dependentUpon = fileItem.DependentUpon;
if (string.IsNullOrEmpty(dependentUpon))
continue;
string directory = Path.GetDirectoryName(fileItem.FileName);
dependentUpon = Path.Combine(directory, dependentUpon);
if (FileUtility.IsEqualFileName(dependentUpon, oldFileName)) {
fileItem.DependentUpon = FileUtility.GetRelativePath(directory, newFileName);
string fileName = Path.GetFileName(fileItem.FileName);
if (fileName.StartsWith(oldPrefix)) {
RenameFile(p, fileItem.FileName, Path.Combine(directory, newPrefix + fileName.Substring(oldPrefix.Length)));
}
}
}
}
}
void ExtractInterface(object sender, EventArgs e)
{
MenuCommand item = (MenuCommand)sender;
FindReferencesAndRenameHelper.ExtractInterface((IClass)item.Tag);
}
void GoToBase(object sender, EventArgs e) void GoToBase(object sender, EventArgs e)
{ {
MenuCommand item = (MenuCommand)sender; MenuCommand item = (MenuCommand)sender;
@ -227,12 +99,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
} }
} }
void Rename(object sender, EventArgs e)
{
MenuCommand item = (MenuCommand)sender;
FindReferencesAndRenameHelper.RenameClass((IClass)item.Tag);
}
void FindDerivedClasses(object sender, EventArgs e) void FindDerivedClasses(object sender, EventArgs e)
{ {
MenuCommand item = (MenuCommand)sender; MenuCommand item = (MenuCommand)sender;
@ -264,5 +130,69 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
IClass c = (IClass)item.Tag; IClass c = (IClass)item.Tag;
FindReferencesAndRenameHelper.RunFindReferences(c); FindReferencesAndRenameHelper.RunFindReferences(c);
} }
public static IClass GetClass(object menuOwner)
{
IClass c;
ClassNode classNode = menuOwner as ClassNode;
if (classNode != null) {
c = classNode.Class;
} else {
ClassBookmark bookmark = (ClassBookmark)menuOwner;
c = bookmark.Class;
}
ParserService.ParseCurrentViewContent();
c = c.ProjectContent.GetClass(c.FullyQualifiedName, c.TypeParameters.Count, c.ProjectContent.Language, GetClassOptions.LookForInnerClass);
c = GetCurrentPart(c);
return c;
}
static IClass GetCurrentPart(IClass possibleCompound)
{
IViewContent viewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
if (viewContent != null)
return GetPart(possibleCompound, viewContent.PrimaryFileName);
else
return GetPart(possibleCompound, null);
}
/// <summary>
/// Gets a specific part of the compound class.
/// </summary>
static IClass GetPart(IClass possibleCompound, string fileName)
{
CompoundClass compound = possibleCompound as CompoundClass;
if (compound == null)
return possibleCompound;
IList<IClass> parts = compound.Parts;
if (!string.IsNullOrEmpty(fileName)) {
// get the part with the requested file name
foreach (IClass part in parts) {
if (FileUtility.IsEqualFileName(fileName, part.CompilationUnit.FileName))
return part;
}
}
// Fallback: get the part with the shortest file name.
// This should prefer non-designer files over designer files.
IClass preferredClass = parts[0];
for (int i = 1; i < parts.Count; i++) {
if (IsShorterFileName(parts[i].CompilationUnit.FileName, preferredClass.CompilationUnit.FileName))
preferredClass = parts[i];
}
return preferredClass;
}
static bool IsShorterFileName(string a, string b)
{
// Fix forum-17295: compilation unit's file name might be null: prefer the non-null file
if (a == null)
return false;
if (b == null)
return true;
return a.Length < b.Length;
}
} }
} }

5
src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs

@ -46,7 +46,10 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} }
/// <summary> /// <summary>
/// Build a menu with refactoring commands for the item that has been clicked on in the text editor. /// Build refactoring commands for the item that has been clicked on in the text editor.
/// The commands are inserted to the top level of the context menu.
/// Path:
/// /SharpDevelop/ViewContent/TextEditor/ContextMenu, id=Refactoring
/// </summary> /// </summary>
public class RefactoringMenuBuilder : IMenuItemBuilder public class RefactoringMenuBuilder : IMenuItemBuilder
{ {

Loading…
Cancel
Save