From 869779a47c382bb8f46d22915ba3538847fc0433 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 19 May 2005 15:51:52 +0000 Subject: [PATCH] Implemented "rename" refactoring. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@150 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/ICSharpCode.SharpDevelop.csproj | 2 +- .../Src/Commands/ClassMemberMenuBuilder.cs | 53 +++++- ...ectContent.cs => DefaultProjectContent.cs} | 0 .../Services/ParserService/ParserService.cs | 9 ++ .../ParseableFileContentEnumerator.cs | 36 ++++- src/Main/Core/Project/ICSharpCode.Core.csproj | 1 + .../Src/Services/MessageService/InputBox.cs | 151 ++++++++++++++++++ .../Services/MessageService/MessageService.cs | 10 +- 8 files changed, 253 insertions(+), 9 deletions(-) rename src/Main/Base/Project/Src/Services/ParserService/{CaseSensitiveProjectContent.cs => DefaultProjectContent.cs} (100%) create mode 100644 src/Main/Core/Project/Src/Services/MessageService/InputBox.cs diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index b197440db2..b5561ac7a4 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -425,7 +425,7 @@ - + diff --git a/src/Main/Base/Project/Src/Commands/ClassMemberMenuBuilder.cs b/src/Main/Base/Project/Src/Commands/ClassMemberMenuBuilder.cs index 2af359c5ae..2091fd2128 100644 --- a/src/Main/Base/Project/Src/Commands/ClassMemberMenuBuilder.cs +++ b/src/Main/Base/Project/Src/Commands/ClassMemberMenuBuilder.cs @@ -75,11 +75,62 @@ namespace ICSharpCode.SharpDevelop.Commands } } + private struct Modification { + public IDocument Document; + public int Offset; + public int LengthDifference; + + public Modification(IDocument Document, int Offset, int LengthDifference) + { + this.Document = Document; + this.Offset = Offset; + this.LengthDifference = LengthDifference; + } + } + void Rename(object sender, EventArgs e) { MenuCommand item = (MenuCommand)sender; IMember member = (IMember)item.Tag; - MessageService.ShowMessage("Not implemented."); + string newName = MessageService.ShowInputBox("Rename", "Enter the new name of the member", member.Name); + if (newName == null || newName.Length == 0) return; + + List list = RefactoringService.FindReferences(member, null); + if (list == null) return; + List modifiedContents = new List(); + List modifications = new List(); + foreach (Reference r in list) { + FileService.OpenFile(r.FileName); + IViewContent viewContent = FileService.GetOpenFile(r.FileName).ViewContent; + if (!modifiedContents.Contains(viewContent)) { + modifiedContents.Add(viewContent); + } + ITextEditorControlProvider p = viewContent as ITextEditorControlProvider; + if (p != null) { + IDocument doc = p.TextEditorControl.Document; + int offset = r.Offset; + foreach (Modification m in modifications) { + if (m.Document != doc) continue; + if (m.Offset < offset) offset += m.LengthDifference; + } + int lengthDifference = newName.Length - r.Length; + doc.Replace(offset, r.Length, newName); + if (lengthDifference != 0) { + for (int i = 0; i < modifications.Count; ++i) { + Modification m = modifications[i]; + if (m.Document != doc) continue; + if (m.Offset > offset) { + m.Offset += lengthDifference; + modifications[i] = m; // Modification is a value type + } + } + modifications.Add(new Modification(doc, offset, lengthDifference)); + } + } + } + foreach (IViewContent viewContent in modifiedContents) { + ParserService.ParseViewContent(viewContent); + } } void FindOverrides(object sender, EventArgs e) diff --git a/src/Main/Base/Project/Src/Services/ParserService/CaseSensitiveProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs similarity index 100% rename from src/Main/Base/Project/Src/Services/ParserService/CaseSensitiveProjectContent.cs rename to src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs index 6f26e44d94..d6ddd4ace4 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs @@ -248,6 +248,15 @@ namespace ICSharpCode.Core } } + public static void ParseViewContent(IViewContent viewContent) + { + string text = ((IEditable)viewContent).Text; + ParseInformation parseInformation = ParseFile(viewContent.FileName, text, !viewContent.IsUntitled, true); + if (parseInformation != null && viewContent is IParseInformationListener) { + ((IParseInformationListener)viewContent).ParseInformationUpdated(parseInformation); + } + } + public static event ParserUpdateStepEventHandler ParserUpdateStepFinished; static void OnParserUpdateStepFinished(ParserUpdateStepEventArgs e) diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs index ebd797c6ff..698d237670 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.SharpDevelop.Project { @@ -76,11 +77,14 @@ namespace ICSharpCode.SharpDevelop.Project string GetParseableFileContent(IProject project, string fileName) { + //Console.WriteLine("Reading {0} from disk", fileName); + // Loading the source files is done asynchronously: // While one file is parsed, the next is already loaded from disk. string res = project.GetParseableFileContent(fileName); if (res != null) return res; + // load file using (StreamReader r = new StreamReader(fileName, getParseableContentEncoding)) { return r.ReadToEnd(); @@ -110,18 +114,38 @@ namespace ICSharpCode.SharpDevelop.Project if (item == null) return false; if (item.ItemType != ItemType.Compile) return MoveNext(); - string fileName = item.FileName; string fileContent; - if (res != null) + if (res != null) { fileContent = pcd.EndInvoke(res); - else - fileContent = GetParseableFileContent(item.Project, fileName); - if (nextItem != null && nextItem.ItemType == ItemType.Compile) + } else { + fileContent = GetFileContent(item); + } + if (nextItem != null && nextItem.ItemType == ItemType.Compile && CanReadAsync(nextItem)) res = pcd.BeginInvoke(nextItem.Project, nextItem.FileName, null, null); else res = null; - current = new KeyValuePair(fileName, fileContent); + current = new KeyValuePair(item.FileName, fileContent); return true; } + + string GetFileContent(ProjectItem item) + { + string fileName = item.FileName; + IWorkbenchWindow window = FileService.GetOpenFile(fileName); + if (window != null) { + IViewContent viewContent = window.ViewContent; + IEditable editable = viewContent as IEditable; + if (editable != null) { + //Console.WriteLine("Reading {0} from editable", fileName); + return editable.Text; + } + } + return GetParseableFileContent(item.Project, fileName); + } + + bool CanReadAsync(ProjectItem item) + { + return !FileService.IsOpen(item.FileName); + } } } diff --git a/src/Main/Core/Project/ICSharpCode.Core.csproj b/src/Main/Core/Project/ICSharpCode.Core.csproj index ca9be0cae4..1b0cea29a6 100644 --- a/src/Main/Core/Project/ICSharpCode.Core.csproj +++ b/src/Main/Core/Project/ICSharpCode.Core.csproj @@ -123,6 +123,7 @@ + \ No newline at end of file diff --git a/src/Main/Core/Project/Src/Services/MessageService/InputBox.cs b/src/Main/Core/Project/Src/Services/MessageService/InputBox.cs new file mode 100644 index 0000000000..67469d8859 --- /dev/null +++ b/src/Main/Core/Project/Src/Services/MessageService/InputBox.cs @@ -0,0 +1,151 @@ +// +// +// +// +// +// + +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace ICSharpCode.Core +{ + /// + /// Description of InputBox. + /// + internal class InputBox : System.Windows.Forms.Form + { + private System.Windows.Forms.Label label; + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.TextBox textBox; + private System.Windows.Forms.Button acceptButton; + + public InputBox(string text, string caption, string defaultValue) + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + text = StringParser.Parse(text); + this.Text = StringParser.Parse(caption); + acceptButton.Text = StringParser.Parse("${res:Global.OKButtonText}"); + cancelButton.Text = StringParser.Parse("${res:Global.CancelButtonText}"); + + Size size; + using (Graphics g = this.CreateGraphics()) { + Rectangle screen = Screen.PrimaryScreen.WorkingArea; + SizeF sizeF = g.MeasureString(text, label.Font, screen.Width - 20); + size = sizeF.ToSize(); + size.Width += 4; + } + if (size.Width < 200) + size.Width = 200; + Size clientSize = this.ClientSize; + clientSize.Width += size.Width - label.Width; + clientSize.Height += size.Height - label.Height; + this.ClientSize = clientSize; + label.Text = text; + textBox.Text = defaultValue; + this.DialogResult = DialogResult.Cancel; + } + + #region Windows Forms Designer generated code + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() { + this.acceptButton = new System.Windows.Forms.Button(); + this.textBox = new System.Windows.Forms.TextBox(); + this.cancelButton = new System.Windows.Forms.Button(); + this.label = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // acceptButton + // + this.acceptButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.acceptButton.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.acceptButton.Location = new System.Drawing.Point(176, 114); + this.acceptButton.Name = "acceptButton"; + this.acceptButton.TabIndex = 2; + this.acceptButton.Text = "OK"; + this.acceptButton.Click += new System.EventHandler(this.AcceptButtonClick); + // + // textBox + // + this.textBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox.Location = new System.Drawing.Point(8, 86); + this.textBox.Name = "textBox"; + this.textBox.Size = new System.Drawing.Size(318, 20); + this.textBox.TabIndex = 1; + this.textBox.Text = ""; + // + // cancelButton + // + this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.cancelButton.Location = new System.Drawing.Point(256, 114); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.TabIndex = 3; + this.cancelButton.Text = "Cancel"; + this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick); + // + // label + // + this.label.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label.Location = new System.Drawing.Point(8, 8); + this.label.Name = "label"; + this.label.Size = new System.Drawing.Size(328, 74); + this.label.TabIndex = 0; + this.label.UseMnemonic = false; + // + // InputBox + // + this.AcceptButton = this.acceptButton; + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(338, 144); + this.Controls.Add(this.textBox); + this.Controls.Add(this.label); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.acceptButton); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InputBox"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "InputBox"; + this.ResumeLayout(false); + } + #endregion + + void CancelButtonClick(object sender, System.EventArgs e) + { + result = null; + this.Close(); + } + + void AcceptButtonClick(object sender, System.EventArgs e) + { + this.DialogResult = DialogResult.OK; + result = textBox.Text; + this.Close(); + } + + string result; + + public string Result { + get { + return result; + } + } + } +} diff --git a/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs b/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs index 7fc65f087c..081ccd1008 100644 --- a/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs +++ b/src/Main/Core/Project/Src/Services/MessageService/MessageService.cs @@ -115,12 +115,20 @@ namespace ICSharpCode.Core return messageBox.Result; } } - + public static int ShowCustomDialog(string caption, string dialogText, params string[] buttontexts) { return ShowCustomDialog(caption, dialogText, -1, -1, buttontexts); } + public static string ShowInputBox(string caption, string dialogText, string defaultValue) + { + using (InputBox inputBox = new InputBox(dialogText, caption, defaultValue)) { + inputBox.ShowDialog(MessageService.MainForm); + return inputBox.Result; + } + } + public static void ShowMessage(string message) { ShowMessage(message, "SharpDevelop");