Browse Source

Fixed SD2-1471 (Renaming MainForm event handler does not update MainForm.Designer file) by adding IFileDocumentProvider as a generalization of ITextEditorControlProvider to properly support view contents that open multiple documents.

Adaptations to ParserService and ParseableFileContentEnumerator to make sure they always use the most recent version of the file content.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3601 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Christian Hornung 18 years ago
parent
commit
1850c9362d
  1. 7
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTextEditorViewContent.cs
  2. 7
      src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs
  3. 8
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs
  4. 13
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs
  5. 10
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs
  6. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  7. 4
      src/Main/Base/Project/Src/Services/File/FileService.cs
  8. 10
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
  9. 30
      src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs
  10. 53
      src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs
  11. 27
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/IFileDocumentProvider.cs
  12. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/ITextAreaControlProvider.cs
  13. 6
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorBasedPad.cs
  14. 9
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

7
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTextEditorViewContent.cs

@ -6,8 +6,10 @@
// </file> // </file>
using System; using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.TextEditor; using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
namespace PythonBinding.Tests.Utils namespace PythonBinding.Tests.Utils
{ {
@ -27,5 +29,10 @@ namespace PythonBinding.Tests.Utils
public TextEditorControl TextEditorControl { public TextEditorControl TextEditorControl {
get { return textEditor; } get { return textEditor; }
} }
public IDocument GetDocumentForFile(OpenedFile file)
{
throw new NotImplementedException();
}
} }
} }

7
src/AddIns/BackendBindings/WixBinding/Test/Utils/MockTextEditorViewContent.cs

@ -6,9 +6,11 @@
// </file> // </file>
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.TextEditor; using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
@ -31,6 +33,11 @@ namespace WixBinding.Tests.Utils
return null; return null;
} }
} }
public IDocument GetDocumentForFile(OpenedFile file)
{
return null;
}
#endregion #endregion
} }

8
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs

@ -192,13 +192,7 @@ namespace ICSharpCode.FormsDesigner
if (formClass.Name != this.formClass.Name) { if (formClass.Name != this.formClass.Name) {
LoggingService.Info("Renaming form to " + formClass.Name); LoggingService.Info("Renaming form to " + formClass.Name);
Dictionary<string, IDocument> providedFileDocuments = new Dictionary<string, IDocument>(); ICSharpCode.SharpDevelop.Refactoring.FindReferencesAndRenameHelper.RenameClass(this.formClass, formClass.Name);
providedFileDocuments.Add(this.ViewContent.DesignerCodeFile.FileName, this.ViewContent.DesignerCodeFileDocument);
if (!this.ViewContent.PrimaryFile.Equals(this.ViewContent.DesignerCodeFile)) {
System.Diagnostics.Debug.Assert(!this.ViewContent.DesignerCodeFileDocument.Equals(this.ViewContent.PrimaryFileDocument));
providedFileDocuments.Add(this.ViewContent.PrimaryFileName, this.ViewContent.PrimaryFileDocument);
}
ICSharpCode.SharpDevelop.Refactoring.FindReferencesAndRenameHelper.RenameClass(this.formClass, formClass.Name, providedFileDocuments);
this.ViewContent.DesignerCodeFile.MakeDirty(); this.ViewContent.DesignerCodeFile.MakeDirty();
this.ViewContent.PrimaryFile.MakeDirty(); this.ViewContent.PrimaryFile.MakeDirty();
Reparse(); Reparse();

13
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs

@ -27,7 +27,7 @@ using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.FormsDesigner namespace ICSharpCode.FormsDesigner
{ {
public class FormsDesignerViewContent : AbstractViewContentHandlingLoadErrors, IClipboardHandler, IUndoHandler, IHasPropertyContainer, IContextHelpProvider, IToolsHost public class FormsDesignerViewContent : AbstractViewContentHandlingLoadErrors, IClipboardHandler, IUndoHandler, IHasPropertyContainer, IContextHelpProvider, IToolsHost, IFileDocumentProvider
{ {
readonly Control pleaseWaitLabel = new Label() {Text=StringParser.Parse("${res:Global.PleaseWait}"), TextAlign=ContentAlignment.MiddleCenter}; readonly Control pleaseWaitLabel = new Label() {Text=StringParser.Parse("${res:Global.PleaseWait}"), TextAlign=ContentAlignment.MiddleCenter};
DesignSurface designSurface; DesignSurface designSurface;
@ -93,6 +93,17 @@ namespace ICSharpCode.FormsDesigner
get { return this.designerCodeFileEncoding; } get { return this.designerCodeFileEncoding; }
} }
public IDocument GetDocumentForFile(OpenedFile file)
{
if (file == this.DesignerCodeFile) {
return this.DesignerCodeFileDocument;
} else if (file == this.PrimaryFile) {
return this.PrimaryFileDocument;
} else {
return null;
}
}
public IViewContent PrimaryViewContent { public IViewContent PrimaryViewContent {
get { return this.primaryViewContent; } get { return this.primaryViewContent; }
} }

10
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs

@ -699,6 +699,16 @@ namespace ICSharpCode.XmlEditor
return xmlEditor; return xmlEditor;
} }
} }
public IDocument GetDocumentForFile(OpenedFile file)
{
if (file == this.PrimaryFile) {
return this.TextEditorControl.Document;
} else {
return null;
}
}
#endregion #endregion
#region IPositionable interface #region IPositionable interface

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

@ -511,6 +511,7 @@
<Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\CodeCompletionDataProvider.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\CodeCompletionDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\CommentCompletionDataProvider.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\CommentCompletionDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\TemplateCompletionDataProvider.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\TemplateCompletionDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\IFileDocumentProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\InsightWindow\IndexerInsightDataProvider.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\InsightWindow\IndexerInsightDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\InsightWindow\MethodInsightDataProvider.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\InsightWindow\MethodInsightDataProvider.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\ErrorDrawer.cs" /> <Compile Include="Src\TextEditor\Gui\Editor\ErrorDrawer.cs" />

4
src/Main/Base/Project/Src/Services/File/FileService.cs

@ -295,6 +295,10 @@ namespace ICSharpCode.SharpDevelop
} }
} }
/// <summary>
/// Gets a list of the names of the files that are open as primary files
/// in view contents.
/// </summary>
public static IList<string> GetOpenFiles() public static IList<string> GetOpenFiles()
{ {
List<string> fileNames = new List<string>(); List<string> fileNames = new List<string>();

10
src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

@ -14,9 +14,11 @@ using System.Text;
using System.Threading; using System.Threading;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor.Document;
using RegistryContentPair = System.Collections.Generic.KeyValuePair<ICSharpCode.SharpDevelop.Dom.ProjectContentRegistry, ICSharpCode.SharpDevelop.Dom.IProjectContent>; using RegistryContentPair = System.Collections.Generic.KeyValuePair<ICSharpCode.SharpDevelop.Dom.ProjectContentRegistry, ICSharpCode.SharpDevelop.Dom.IProjectContent>;
@ -638,6 +640,14 @@ namespace ICSharpCode.SharpDevelop
OpenedFile file = FileService.GetOpenedFile(fileName); OpenedFile file = FileService.GetOpenedFile(fileName);
if (file != null) { if (file != null) {
IFileDocumentProvider p = file.CurrentView as IFileDocumentProvider;
if (p != null) {
IDocument document = p.GetDocumentForFile(file);
if (document != null) {
return document.TextContent;
}
}
using(Stream s = file.OpenRead()) { using(Stream s = file.OpenRead()) {
// load file // load file
Encoding encoding = DefaultFileEncoding; Encoding encoding = DefaultFileEncoding;

30
src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs

@ -12,7 +12,9 @@ using System.IO;
using System.Text; using System.Text;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop.Project namespace ICSharpCode.SharpDevelop.Project
{ {
@ -83,6 +85,25 @@ namespace ICSharpCode.SharpDevelop.Project
// Loading the source files is done asynchronously: // Loading the source files is done asynchronously:
// While one file is parsed, the next is already loaded from disk. // While one file is parsed, the next is already loaded from disk.
// Load file from memory if it is open
OpenedFile file = FileService.GetOpenedFile(fileName);
if (file != null) {
string content;
if (isOnMainThread) {
content = GetFileContentFromFileDocumentProvider(file);
} else {
content = WorkbenchSingleton.SafeThreadFunction<OpenedFile, string>(GetFileContentFromFileDocumentProvider, file);
}
if (content != null) {
return content;
}
using(Stream s = file.OpenRead()) {
Encoding encoding = defaultEncoding;
return ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(s, ref encoding);
}
}
// load file // load file
return ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(fileName, defaultEncoding); return ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(fileName, defaultEncoding);
} }
@ -165,5 +186,14 @@ namespace ICSharpCode.SharpDevelop.Project
} }
return null; return null;
} }
static string GetFileContentFromFileDocumentProvider(OpenedFile file)
{
IFileDocumentProvider p = file.CurrentView as IFileDocumentProvider;
if (p == null) return null;
IDocument document = p.GetDocumentForFile(file);
if (document == null) return null;
return document.TextContent;
}
} }
} }

53
src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs

@ -131,11 +131,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} }
public static void RenameClass(IClass c, string newName) public static void RenameClass(IClass c, string newName)
{
RenameClass(c, newName, null);
}
public static void RenameClass(IClass c, string newName, IDictionary<string, ICSharpCode.TextEditor.Document.IDocument> providedFileDocuments)
{ {
c = c.GetCompoundClass(); // get compound class if class is partial c = c.GetCompoundClass(); // get compound class if class is partial
@ -154,7 +149,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} }
} }
FindReferencesAndRenameHelper.RenameReferences(list, newName, providedFileDocuments); FindReferencesAndRenameHelper.RenameReferences(list, newName);
} }
static IList<IClass> GetClassParts(IClass c) static IList<IClass> GetClassParts(IClass c)
@ -369,25 +364,36 @@ namespace ICSharpCode.SharpDevelop.Refactoring
SearchResultPanel.Instance.ShowSearchResults(new SearchResult(pattern, results)); SearchResultPanel.Instance.ShowSearchResults(new SearchResult(pattern, results));
} }
public static void RenameReferences(List<Reference> list, string newName) sealed class FileView {
{ public IViewContent ViewContent { get; set; }
RenameReferences(list, newName, null); public OpenedFile OpenedFile { get; set; }
} }
public static void RenameReferences(List<Reference> list, string newName, IDictionary<string, ICSharpCode.TextEditor.Document.IDocument> providedFileDocuments) public static void RenameReferences(List<Reference> list, string newName)
{ {
Dictionary<ICSharpCode.TextEditor.Document.IDocument, IViewContent> modifiedDocuments = new Dictionary<ICSharpCode.TextEditor.Document.IDocument, IViewContent>(); Dictionary<ICSharpCode.TextEditor.Document.IDocument, FileView> modifiedDocuments = new Dictionary<ICSharpCode.TextEditor.Document.IDocument, FileView>();
List<Modification> modifications = new List<Modification>(); List<Modification> modifications = new List<Modification>();
foreach (Reference r in list) { foreach (Reference r in list) {
ICSharpCode.TextEditor.Document.IDocument document; ICSharpCode.TextEditor.Document.IDocument document = null;
IViewContent viewContent; IViewContent viewContent = null;
if (providedFileDocuments == null || !providedFileDocuments.TryGetValue(FileUtility.NormalizePath(r.FileName), out document)) { OpenedFile file = FileService.GetOpenedFile(r.FileName);
if (file != null) {
viewContent = file.CurrentView;
IFileDocumentProvider p = viewContent as IFileDocumentProvider;
if (p != null) {
document = p.GetDocumentForFile(file);
}
}
if (document == null) {
viewContent = FileService.OpenFile(r.FileName, false); viewContent = FileService.OpenFile(r.FileName, false);
ITextEditorControlProvider p = viewContent as ITextEditorControlProvider; IFileDocumentProvider p = viewContent as IFileDocumentProvider;
document = (p == null) ? null : p.TextEditorControl.Document; if (p != null) {
} else { file = FileService.GetOpenedFile(r.FileName);
viewContent = null; System.Diagnostics.Debug.Assert(file != null, "OpenedFile not found after opening the file.");
document = p.GetDocumentForFile(file);
}
} }
if (document == null) { if (document == null) {
@ -396,16 +402,19 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} }
if (!modifiedDocuments.ContainsKey(document)) { if (!modifiedDocuments.ContainsKey(document)) {
modifiedDocuments.Add(document, viewContent); modifiedDocuments.Add(document, new FileView() {ViewContent = viewContent, OpenedFile = file});
document.UndoStack.StartUndoGroup(); document.UndoStack.StartUndoGroup();
} }
ModifyDocument(modifications, document, r.Offset, r.Length, newName); ModifyDocument(modifications, document, r.Offset, r.Length, newName);
} }
foreach (KeyValuePair<ICSharpCode.TextEditor.Document.IDocument, IViewContent> entry in modifiedDocuments) { foreach (KeyValuePair<ICSharpCode.TextEditor.Document.IDocument, FileView> entry in modifiedDocuments) {
entry.Key.UndoStack.EndUndoGroup(); entry.Key.UndoStack.EndUndoGroup();
if (entry.Value != null) { entry.Value.OpenedFile.MakeDirty();
ParserService.ParseViewContent(entry.Value); if (entry.Value.ViewContent is IEditable) {
ParserService.ParseViewContent(entry.Value.ViewContent);
} else {
ParserService.ParseFile(entry.Value.OpenedFile.FileName, entry.Key.TextContent, !entry.Value.OpenedFile.IsUntitled);
} }
} }
} }

27
src/Main/Base/Project/Src/TextEditor/Gui/Editor/IFileDocumentProvider.cs

@ -0,0 +1,27 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{
/// <summary>
/// Interface for view contents that provide a text editor document
/// for one or more <see cref="OpenedFile"/>s.
/// </summary>
public interface IFileDocumentProvider
{
/// <summary>
/// Gets the edited document for the specified file.
/// </summary>
/// <param name="file">The <see cref="OpenedFile"/> to get the document for.</param>
/// <returns>The edited document for the specified file, or <c>null</c> if this view does not provide a document for the specified file.</returns>
IDocument GetDocumentForFile(OpenedFile file);
}
}

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/ITextAreaControlProvider.cs

@ -10,7 +10,7 @@ using ICSharpCode.TextEditor;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{ {
public interface ITextEditorControlProvider public interface ITextEditorControlProvider : IFileDocumentProvider
{ {
TextEditorControl TextEditorControl { TextEditorControl TextEditorControl {
get; get;

6
src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorBasedPad.cs

@ -11,6 +11,7 @@ using System.Windows.Forms;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.TextEditor; using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{ {
@ -64,6 +65,11 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
public virtual IDocument GetDocumentForFile(OpenedFile file)
{
return null;
}
PrintDocument IPrintable.PrintDocument { PrintDocument IPrintable.PrintDocument {
get { get {
return this.TextEditorControl.PrintDocument; return this.TextEditorControl.PrintDocument;

9
src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

@ -78,6 +78,15 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
public IDocument GetDocumentForFile(OpenedFile file)
{
if (file == this.PrimaryFile) {
return this.TextEditorControl.Document;
} else {
return null;
}
}
public bool EnableUndo { public bool EnableUndo {
get { get {
return textEditorControl.EnableUndo; return textEditorControl.EnableUndo;

Loading…
Cancel
Save