Browse Source

Fixed build.

Allow unit testing of view contents by decoupling OpenedFile from FileService and Workbench.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2663 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
0333757269
  1. 33
      src/AddIns/BackendBindings/WixBinding/Test/Utils/MockViewContent.cs
  2. 4
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs
  3. 5
      src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewClipboardHandlerTestFixture.cs
  4. 59
      src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockOpenedFile.cs
  5. 1
      src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj
  6. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  7. 2
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/LoadSavePanel.cs
  8. 7
      src/Main/Base/Project/Src/Gui/Pads/PropertyPad/PropertyContainer.cs
  9. 4
      src/Main/Base/Project/Src/Gui/Pads/PropertyPad/PropertyPad.cs
  10. 5
      src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
  11. 126
      src/Main/Base/Project/Src/Services/File/FileChangeWatcher.cs
  12. 4
      src/Main/Base/Project/Src/Services/File/FileService.cs
  13. 464
      src/Main/Base/Project/Src/Services/File/OpenedFile.cs

33
src/AddIns/BackendBindings/WixBinding/Test/Utils/MockViewContent.cs

@ -29,17 +29,39 @@ namespace WixBinding.Tests.Utils @@ -29,17 +29,39 @@ namespace WixBinding.Tests.Utils
public void SetName(string fileName)
{
primaryFile = OpenedFile.CreateDummyOpenedFile(fileName, false);
primaryFile = new MockOpenedFile(fileName, false);
}
public void SetUntitledName(string fileName)
{
primaryFile = OpenedFile.CreateDummyOpenedFile(fileName, true);
primaryFile = new MockOpenedFile(fileName, true);
}
class MockOpenedFile : OpenedFile
{
public MockOpenedFile(string fileName, bool isUntitled)
{
base.FileName = fileName;
base.IsUntitled = isUntitled;
}
public override IList<IViewContent> RegisteredViewContents {
get {
throw new NotImplementedException();
}
}
public override void RegisterView(IViewContent view)
{
}
public override void UnregisterView(IViewContent view)
{
}
}
#pragma warning disable 67
public event EventHandler TabPageTextChanged;
public event EventHandler SwitchedTo;
public event EventHandler Disposed;
public event EventHandler IsDirtyChanged;
public event EventHandler TitleNameChanged;
@ -144,11 +166,6 @@ namespace WixBinding.Tests.Utils @@ -144,11 +166,6 @@ namespace WixBinding.Tests.Utils
}
}
public void OnSwitchedTo()
{
throw new NotImplementedException();
}
public void RedrawContent()
{
throw new NotImplementedException();

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

@ -155,6 +155,7 @@ namespace ICSharpCode.FormsDesigner @@ -155,6 +155,7 @@ namespace ICSharpCode.FormsDesigner
}
UpdatePropertyPad();
PropertyPad.PropertyValueChanged += PropertyValueChanged;
hasUnmergedChanges = false;
@ -208,6 +209,7 @@ namespace ICSharpCode.FormsDesigner @@ -208,6 +209,7 @@ namespace ICSharpCode.FormsDesigner
void UnloadDesigner()
{
PropertyPad.PropertyValueChanged -= PropertyValueChanged;
generator.Detach();
bool savedIsDirty = this.PrimaryFile.IsDirty;
p.Controls.Clear();
@ -579,6 +581,8 @@ namespace ICSharpCode.FormsDesigner @@ -579,6 +581,8 @@ namespace ICSharpCode.FormsDesigner
{
if (e.ChangedItem == null || e.OldValue == null)
return;
if (!propertyContainer.IsActivePropertyContainer)
return;
if (e.ChangedItem.GridItemType == GridItemType.Property) {
if (e.ChangedItem.PropertyDescriptor.Name == "Language") {
if (!e.OldValue.Equals(e.ChangedItem.Value)) {

5
src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewClipboardHandlerTestFixture.cs

@ -35,16 +35,17 @@ namespace XmlEditor.Tests.Tree @@ -35,16 +35,17 @@ namespace XmlEditor.Tests.Tree
[SetUp]
public void SetUp()
{
MockOpenedFile openedFile = new MockOpenedFile("test.xml");
XmlSchemaCompletionDataCollection schemas = new XmlSchemaCompletionDataCollection();
xmlView = new XmlView(new DefaultTextEditorProperties(), schemas);
xmlView.SetPrimaryFileUnitTestMode(OpenedFile.CreateDummyOpenedFile("test.xml", true));
xmlView.SetPrimaryFileUnitTestMode(openedFile);
view = new XmlTreeView(xmlView, null, null);
treeViewContainer = (XmlTreeViewContainerControl)view.Control;
treeView = treeViewContainer.TreeView;
clipboardHandler = view as IClipboardHandler;
xmlView.XmlEditor.Text = "<html><body><p></p></body></html>";
((IViewContent)view).OnSwitchedTo();
openedFile.SwitchToView(view);
htmlTreeNode = treeView.Nodes[0] as XmlElementTreeNode;
htmlTreeNode.PerformInitialization();

59
src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockOpenedFile.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 2658$</version>
// </file>
using System;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop;
using System.Collections.Generic;
namespace XmlEditor.Tests.Utils
{
/// <summary>
/// Description of MockOpenedFile.
/// </summary>
public class MockOpenedFile : OpenedFile
{
public MockOpenedFile(string fileName)
{
base.FileName = fileName;
base.IsUntitled = true;
SetData(new byte[0]);
}
List<IViewContent> registeredViews = new List<IViewContent>();
public override IList<IViewContent> RegisteredViewContents {
get { return registeredViews.AsReadOnly(); }
}
public override void RegisterView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
if (registeredViews.Contains(view))
throw new ArgumentException("registeredViews already contains view");
registeredViews.Add(view);
if (registeredViews.Count == 1)
SwitchedToView(registeredViews[0]);
}
public override void UnregisterView(IViewContent view)
{
if (!registeredViews.Remove(view))
throw new ArgumentException("registeredViews does not contain view");
}
public void SwitchToView(IViewContent view)
{
if (!registeredViews.Contains(view))
throw new ArgumentException("registeredViews does not contain view");
base.SwitchedToView(view);
}
}
}

1
src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj

@ -94,6 +94,7 @@ @@ -94,6 +94,7 @@
<Compile Include="Utils\DerivedXmlTreeView.cs" />
<Compile Include="Utils\DerivedXmlTreeViewContainerControl.cs" />
<Compile Include="Utils\MockAddXmlNodeDialog.cs" />
<Compile Include="Utils\MockOpenedFile.cs" />
<Compile Include="Utils\ResourceManager.cs" />
<Compile Include="Schema\XhtmlStrictSchemaTestFixture.cs" />
<Compile Include="Schema\XsdSchemaTestFixture.cs" />

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

@ -102,6 +102,7 @@ @@ -102,6 +102,7 @@
<Compile Include="Src\Services\DisplayBinding\ExternalProcessDisplayBinding.cs" />
<Compile Include="Src\Services\DisplayBinding\ISecondaryDisplayBinding.cs" />
<Compile Include="Src\Services\DisplayBinding\ShellExecuteDisplayBinding.cs" />
<Compile Include="Src\Services\File\FileChangeWatcher.cs" />
<Compile Include="Src\Services\File\OpenedFile.cs" />
<Compile Include="Src\Services\File\RecentOpen.cs" />
<Compile Include="Src\Services\Language\LanguageService.cs" />

2
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/LoadSavePanel.cs

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
using System;
using System.Windows.Forms;
using ICSharpCode.Core;
using FileChangeWatcher = ICSharpCode.SharpDevelop.OpenedFile.FileChangeWatcher;
using FileChangeWatcher = ICSharpCode.SharpDevelop.FileChangeWatcher;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{

7
src/Main/Base/Project/Src/Gui/Pads/PropertyPad/PropertyContainer.cs

@ -49,6 +49,13 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -49,6 +49,13 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
/// <summary>
/// Gets if this property container is currently shown in the property grid.
/// </summary>
public bool IsActivePropertyContainer {
get { return PropertyPad.ActiveContainer == this; }
}
object selectedObject;
object[] selectedObjects;

4
src/Main/Base/Project/Src/Gui/Pads/PropertyPad/PropertyPad.cs

@ -26,6 +26,10 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -26,6 +26,10 @@ namespace ICSharpCode.SharpDevelop.Gui
PropertyContainer activeContainer;
internal static PropertyContainer ActiveContainer {
get { return instance.activeContainer; }
}
void SetActiveContainer(PropertyContainer pc)
{
if (activeContainer == pc)

5
src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs

@ -21,9 +21,12 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -21,9 +21,12 @@ namespace ICSharpCode.SharpDevelop.Gui
static STAThreadCaller caller;
static DefaultWorkbench workbench;
/// <summary>
/// Gets the main form. Returns null in unit-testing mode.
/// </summary>
public static Form MainForm {
get {
return (Form)workbench;
return workbench as Form;
}
}

126
src/Main/Base/Project/Src/Services/File/FileChangeWatcher.cs

@ -0,0 +1,126 @@ @@ -0,0 +1,126 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop
{
#region FileChangeWatcher
internal sealed class FileChangeWatcher //: IDisposable
{
/*FileSystemWatcher watcher;
bool wasChangedExternally = false;
string fileName;
AbstractViewContent viewContent;
public FileChangeWatcher(AbstractViewContent viewContent)
{
this.viewContent = viewContent;
WorkbenchSingleton.MainForm.Activated += GotFocusEvent;
}
*/
public static bool DetectExternalChangesOption {
get {
return PropertyService.Get("SharpDevelop.FileChangeWatcher.DetectExternalChanges", true);
}
set {
PropertyService.Set("SharpDevelop.FileChangeWatcher.DetectExternalChanges", value);
}
}
public static bool AutoLoadExternalChangesOption {
get {
return PropertyService.Get("SharpDevelop.FileChangeWatcher.AutoLoadExternalChanges", true);
}
set {
PropertyService.Set("SharpDevelop.FileChangeWatcher.AutoLoadExternalChanges", value);
}
}
/*
public void Dispose()
{
WorkbenchSingleton.MainForm.Activated -= GotFocusEvent;
if (watcher != null) {
watcher.Dispose();
}
}
public void Disable()
{
if (watcher != null) {
watcher.EnableRaisingEvents = false;
}
}
public void SetWatcher(string fileName)
{
this.fileName = fileName;
if (DetectExternalChangesOption == false)
return;
try {
if (this.watcher == null) {
this.watcher = new FileSystemWatcher();
this.watcher.SynchronizingObject = WorkbenchSingleton.MainForm;
this.watcher.Changed += new FileSystemEventHandler(this.OnFileChangedEvent);
} else {
this.watcher.EnableRaisingEvents = false;
}
this.watcher.Path = Path.GetDirectoryName(fileName);
this.watcher.Filter = Path.GetFileName(fileName);
this.watcher.NotifyFilter = NotifyFilters.LastWrite;
this.watcher.EnableRaisingEvents = true;
} catch (PlatformNotSupportedException) {
if (watcher != null) {
watcher.Dispose();
}
watcher = null;
}
}
void OnFileChangedEvent(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Deleted) {
wasChangedExternally = true;
if (ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench.IsActiveWindow) {
// delay showing message a bit, prevents showing two messages
// when the file changes twice in quick succession
WorkbenchSingleton.SafeThreadAsyncCall(GotFocusEvent, this, EventArgs.Empty);
}
}
}
void GotFocusEvent(object sender, EventArgs e)
{
if (wasChangedExternally) {
wasChangedExternally = false;
string message = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.TextEditorDisplayBinding.FileAlteredMessage}", new string[,] {{"File", Path.GetFullPath(fileName)}});
if ((AutoLoadExternalChangesOption && viewContent.IsDirty == false)
|| MessageBox.Show(message,
StringParser.Parse("${res:MainWindow.DialogName}"),
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
if (File.Exists(fileName)) {
viewContent.Load(fileName);
}
} else {
viewContent.IsDirty = true;
}
}
}
*/
}
#endregion
}

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

@ -99,7 +99,7 @@ namespace ICSharpCode.SharpDevelop @@ -99,7 +99,7 @@ namespace ICSharpCode.SharpDevelop
fileName = FileUtility.NormalizePath(fileName);
OpenedFile file;
if (!openedFileDict.TryGetValue(fileName, out file)) {
openedFileDict[fileName] = file = new OpenedFile(fileName);
openedFileDict[fileName] = file = new FileServiceOpenedFile(fileName);
}
return file;
}
@ -112,7 +112,7 @@ namespace ICSharpCode.SharpDevelop @@ -112,7 +112,7 @@ namespace ICSharpCode.SharpDevelop
if (defaultName == null)
throw new ArgumentNullException("defaultName");
OpenedFile file = new OpenedFile(content);
OpenedFile file = new FileServiceOpenedFile(content);
file.FileName = file.GetHashCode() + "/" + defaultName;
openedFileDict[file.FileName] = file;
return file;

464
src/Main/Base/Project/Src/Services/File/OpenedFile.cs

@ -17,14 +17,11 @@ namespace ICSharpCode.SharpDevelop @@ -17,14 +17,11 @@ namespace ICSharpCode.SharpDevelop
/// <summary>
/// Represents an opened file.
/// </summary>
public sealed class OpenedFile : ICanBeDirty
public abstract class OpenedFile : ICanBeDirty
{
bool isConnectedWithFileService = true;
string fileName;
IViewContent currentView;
bool isUntitled;
List<IViewContent> registeredViews = new List<IViewContent>();
protected IViewContent currentView;
bool inLoadOperation;
bool inSaveOperation;
/// <summary>
/// holds unsaved file content in memory when view containing the file was closed but no other view
@ -32,41 +29,52 @@ namespace ICSharpCode.SharpDevelop @@ -32,41 +29,52 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
byte[] fileData;
internal OpenedFile(string fileName)
{
this.fileName = fileName;
isUntitled = false;
}
#region IsDirty
bool isDirty;
public event EventHandler IsDirtyChanged;
internal OpenedFile(byte[] fileData)
{
this.fileName = null;
this.fileData = fileData;
isUntitled = true;
MakeDirty();
/// <summary>
/// Gets/sets if the file is has unsaved changes.
/// </summary>
public bool IsDirty {
get { return isDirty;}
set {
if (isDirty != value) {
isDirty = value;
if (IsDirtyChanged != null) {
IsDirtyChanged(this, EventArgs.Empty);
}
}
}
}
/// <summary>
/// Creates a dummy opened file instance. Use for unit tests only!
/// Marks the file as dirty if it currently is not in a load operation.
/// </summary>
public static OpenedFile CreateDummyOpenedFile(string name, bool isUntitled)
public virtual void MakeDirty()
{
if (isUntitled) {
OpenedFile f = new OpenedFile(new byte[0]);
f.isConnectedWithFileService = false;
f.FileName = name;
return f;
} else {
OpenedFile f = new OpenedFile(name);
f.isConnectedWithFileService = false;
return f;
if (!inLoadOperation) {
this.IsDirty = true;
}
}
#endregion
bool isUntitled;
/// <summary>
/// Gets if the file is untitled. Untitled files show a "Save as" dialog when they are saved.
/// </summary>
public bool IsUntitled {
get { return isUntitled; }
protected set { isUntitled = value; }
}
string fileName;
/// <summary>
/// Gets the name of the file.
/// </summary>
public string FileName {
get { return fileName; }
set {
@ -75,25 +83,71 @@ namespace ICSharpCode.SharpDevelop @@ -75,25 +83,71 @@ namespace ICSharpCode.SharpDevelop
value = FileUtility.NormalizePath(value);
if (fileName != value) {
if (isConnectedWithFileService) {
FileService.OpenedFileFileNameChange(this, fileName, value);
}
fileName = value;
if (FileNameChanged != null) {
FileNameChanged(this, EventArgs.Empty);
}
ChangeFileName(value);
}
}
}
protected virtual void ChangeFileName(string newValue)
{
fileName = newValue;
if (FileNameChanged != null) {
FileNameChanged(this, EventArgs.Empty);
}
}
/// <summary>
/// Occurs when the file name has changed.
/// </summary>
public event EventHandler FileNameChanged;
/// <summary>
/// Use this method to save the file to disk using a new name.
/// </summary>
public void SaveToDisk(string newFileName)
{
this.FileName = newFileName;
this.IsUntitled = false;
SaveToDisk();
}
public abstract void RegisterView(IViewContent view);
public abstract void UnregisterView(IViewContent view);
public virtual void CloseIfAllViewsClosed()
{
}
/// <summary>
/// Forces initialization of the specified view.
/// </summary>
public virtual void ForceInitializeView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
if (currentView != view) {
if (currentView == null) {
SwitchedToView(view);
} else {
try {
inLoadOperation = true;
using (Stream sourceStream = OpenRead()) {
view.Load(this, sourceStream);
}
} finally {
inLoadOperation = false;
}
}
}
}
/// <summary>
/// Gets the list of view contents registered with this opened file.
/// </summary>
public IList<IViewContent> RegisteredViewContents {
get { return registeredViews.AsReadOnly(); }
public abstract IList<IViewContent> RegisteredViewContents {
get;
}
/// <summary>
@ -110,12 +164,12 @@ namespace ICSharpCode.SharpDevelop @@ -110,12 +164,12 @@ namespace ICSharpCode.SharpDevelop
/// <summary>
/// Opens the file for reading.
/// </summary>
public Stream OpenRead()
public virtual Stream OpenRead()
{
if (fileData != null) {
return new MemoryStream(fileData, false);
} else {
return new FileStream(fileName, FileMode.Open, FileAccess.Read);
return new FileStream(FileName, FileMode.Open, FileAccess.Read);
}
}
@ -129,7 +183,7 @@ namespace ICSharpCode.SharpDevelop @@ -129,7 +183,7 @@ namespace ICSharpCode.SharpDevelop
/// for a file that doesn't exist on disk but should be automatically created when a view
/// with the file is saved, e.g. for .resx files created by the forms designer.
/// </remarks>
public void SetData(byte[] fileData)
public virtual void SetData(byte[] fileData)
{
if (fileData == null)
throw new ArgumentNullException("fileData");
@ -141,16 +195,12 @@ namespace ICSharpCode.SharpDevelop @@ -141,16 +195,12 @@ namespace ICSharpCode.SharpDevelop
this.fileData = fileData;
}
public void SaveToDisk(string newFileName)
{
this.FileName = newFileName;
isUntitled = false;
SaveToDisk();
}
public void SaveToDisk()
/// <summary>
/// Save the file to disk using the current name.
/// </summary>
public virtual void SaveToDisk()
{
if (isUntitled)
if (IsUntitled)
throw new InvalidOperationException("Cannot save an untitled file to disk!");
/*
@ -167,7 +217,7 @@ namespace ICSharpCode.SharpDevelop @@ -167,7 +217,7 @@ namespace ICSharpCode.SharpDevelop
}
}
*/
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write)) {
if (currentView != null) {
SaveCurrentViewToStream(fs);
} else {
@ -187,7 +237,6 @@ namespace ICSharpCode.SharpDevelop @@ -187,7 +237,6 @@ namespace ICSharpCode.SharpDevelop
// /// </summary>
// public event EventHandler SavedCurrentView;
bool inSaveOperation;
void SaveCurrentViewToStream(Stream stream)
{
@ -203,7 +252,7 @@ namespace ICSharpCode.SharpDevelop @@ -203,7 +252,7 @@ namespace ICSharpCode.SharpDevelop
// SavedCurrentView(this, EventArgs.Empty);
}
void SaveCurrentView()
protected void SaveCurrentView()
{
using (MemoryStream memoryStream = new MemoryStream()) {
SaveCurrentViewToStream(memoryStream);
@ -211,100 +260,8 @@ namespace ICSharpCode.SharpDevelop @@ -211,100 +260,8 @@ namespace ICSharpCode.SharpDevelop
}
}
public void RegisterView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
Debug.Assert(!registeredViews.Contains(view));
registeredViews.Add(view);
WorkbenchSingleton.Workbench.ActiveViewContentChanged += WorkbenchActiveViewContentChanged;
if (WorkbenchSingleton.Workbench.ActiveViewContent == view) {
SwitchedToView(view);
}
#if DEBUG
view.Disposed += ViewDisposed;
#endif
}
public void UnregisterView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
Debug.Assert(registeredViews.Contains(view));
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchActiveViewContentChanged;
#if DEBUG
view.Disposed -= ViewDisposed;
#endif
registeredViews.Remove(view);
if (registeredViews.Count > 0) {
if (currentView == view) {
SaveCurrentView();
currentView = null;
}
} else {
// all views to the file were closed
if (isConnectedWithFileService) {
FileService.OpenedFileClosed(this);
}
}
}
internal void CloseIfAllViewsClosed()
{
if (registeredViews.Count == 0) {
if (isConnectedWithFileService) {
FileService.OpenedFileClosed(this);
}
}
}
#if DEBUG
void ViewDisposed(object sender, EventArgs e)
{
Debug.Fail("View was disposed while still registered with OpenedFile!");
}
#endif
/// <summary>
/// Forces initialization of the specified view.
/// </summary>
public void ForceInitializeView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
Debug.Assert(registeredViews.Contains(view));
if (currentView != view) {
if (currentView == null) {
SwitchedToView(view);
} else {
try {
inLoadOperation = true;
using (Stream sourceStream = OpenRead()) {
view.Load(this, sourceStream);
}
} finally {
inLoadOperation = false;
}
}
}
}
void WorkbenchActiveViewContentChanged(object sender, EventArgs e)
{
IViewContent newView = WorkbenchSingleton.Workbench.ActiveViewContent;
if (!registeredViews.Contains(newView))
return;
SwitchedToView(newView);
}
void SwitchedToView(IViewContent newView)
protected void SwitchedToView(IViewContent newView)
{
if (currentView != null) {
if (newView.SupportsSwitchToThisWithoutSaveLoad(this, currentView)
@ -333,7 +290,7 @@ namespace ICSharpCode.SharpDevelop @@ -333,7 +290,7 @@ namespace ICSharpCode.SharpDevelop
}
}
public void ReloadFromDisk()
public virtual void ReloadFromDisk()
{
fileData = null;
if (currentView != null) {
@ -347,157 +304,116 @@ namespace ICSharpCode.SharpDevelop @@ -347,157 +304,116 @@ namespace ICSharpCode.SharpDevelop
}
}
}
}
sealed class FileServiceOpenedFile : OpenedFile
{
List<IViewContent> registeredViews = new List<IViewContent>();
/*
internal void ChangeView(IViewContent newView)
protected override void ChangeFileName(string newValue)
{
if (currentView != null && currentView != newView) {
SaveCurrentView();
}
using (Stream sourceStream = OpenRead()) {
currentView = newView;
fileData = null;
newView.Load(this, sourceStream);
}
FileService.OpenedFileFileNameChange(this, this.FileName, newValue);
base.ChangeFileName(newValue);
}
*/
bool isDirty;
public event EventHandler IsDirtyChanged;
public bool IsDirty {
get { return isDirty;}
set {
if (isDirty != value) {
isDirty = value;
if (IsDirtyChanged != null) {
IsDirtyChanged(this, EventArgs.Empty);
}
}
}
internal FileServiceOpenedFile(string fileName)
{
this.FileName = fileName;
IsUntitled = false;
}
bool inLoadOperation;
internal FileServiceOpenedFile(byte[] fileData)
{
this.FileName = null;
SetData(fileData);
IsUntitled = true;
MakeDirty();
}
/// <summary>
/// Marks the file as dirty if it currently is not in a load operation.
/// Gets the list of view contents registered with this opened file.
/// </summary>
public void MakeDirty()
{
if (!inLoadOperation) {
this.IsDirty = true;
}
public override IList<IViewContent> RegisteredViewContents {
get { return registeredViews.AsReadOnly(); }
}
#region FileChangeWatcher
internal sealed class FileChangeWatcher //: IDisposable
public override void ForceInitializeView(IViewContent view)
{
/*FileSystemWatcher watcher;
bool wasChangedExternally = false;
string fileName;
AbstractViewContent viewContent;
if (view == null)
throw new ArgumentNullException("view");
if (!registeredViews.Contains(view))
throw new ArgumentException("registeredViews must contain view");
public FileChangeWatcher(AbstractViewContent viewContent)
{
this.viewContent = viewContent;
WorkbenchSingleton.MainForm.Activated += GotFocusEvent;
}
*/
base.ForceInitializeView(view);
}
public override void RegisterView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
if (registeredViews.Contains(view))
throw new ArgumentException("registeredViews already contains view");
public static bool DetectExternalChangesOption {
get {
return PropertyService.Get("SharpDevelop.FileChangeWatcher.DetectExternalChanges", true);
}
set {
PropertyService.Set("SharpDevelop.FileChangeWatcher.DetectExternalChanges", value);
}
}
registeredViews.Add(view);
public static bool AutoLoadExternalChangesOption {
get {
return PropertyService.Get("SharpDevelop.FileChangeWatcher.AutoLoadExternalChanges", true);
}
set {
PropertyService.Set("SharpDevelop.FileChangeWatcher.AutoLoadExternalChanges", value);
if (WorkbenchSingleton.Workbench != null) {
WorkbenchSingleton.Workbench.ActiveViewContentChanged += WorkbenchActiveViewContentChanged;
if (WorkbenchSingleton.Workbench.ActiveViewContent == view) {
SwitchedToView(view);
}
}
#if DEBUG
view.Disposed += ViewDisposed;
#endif
}
public override void UnregisterView(IViewContent view)
{
if (view == null)
throw new ArgumentNullException("view");
Debug.Assert(registeredViews.Contains(view));
/*
public void Dispose()
{
WorkbenchSingleton.MainForm.Activated -= GotFocusEvent;
if (watcher != null) {
watcher.Dispose();
}
if (WorkbenchSingleton.Workbench != null) {
WorkbenchSingleton.Workbench.ActiveViewContentChanged -= WorkbenchActiveViewContentChanged;
}
#if DEBUG
view.Disposed -= ViewDisposed;
#endif
public void Disable()
{
if (watcher != null) {
watcher.EnableRaisingEvents = false;
registeredViews.Remove(view);
if (registeredViews.Count > 0) {
if (currentView == view) {
SaveCurrentView();
currentView = null;
}
} else {
// all views to the file were closed
FileService.OpenedFileClosed(this);
}
public void SetWatcher(string fileName)
{
this.fileName = fileName;
if (DetectExternalChangesOption == false)
return;
try {
if (this.watcher == null) {
this.watcher = new FileSystemWatcher();
this.watcher.SynchronizingObject = WorkbenchSingleton.MainForm;
this.watcher.Changed += new FileSystemEventHandler(this.OnFileChangedEvent);
} else {
this.watcher.EnableRaisingEvents = false;
}
this.watcher.Path = Path.GetDirectoryName(fileName);
this.watcher.Filter = Path.GetFileName(fileName);
this.watcher.NotifyFilter = NotifyFilters.LastWrite;
this.watcher.EnableRaisingEvents = true;
} catch (PlatformNotSupportedException) {
if (watcher != null) {
watcher.Dispose();
}
watcher = null;
}
}
public override void CloseIfAllViewsClosed()
{
if (registeredViews.Count == 0) {
FileService.OpenedFileClosed(this);
}
}
#if DEBUG
void ViewDisposed(object sender, EventArgs e)
{
Debug.Fail("View was disposed while still registered with OpenedFile!");
}
#endif
void WorkbenchActiveViewContentChanged(object sender, EventArgs e)
{
IViewContent newView = WorkbenchSingleton.Workbench.ActiveViewContent;
void OnFileChangedEvent(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Deleted) {
wasChangedExternally = true;
if (ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench.IsActiveWindow) {
// delay showing message a bit, prevents showing two messages
// when the file changes twice in quick succession
WorkbenchSingleton.SafeThreadAsyncCall(GotFocusEvent, this, EventArgs.Empty);
}
}
}
if (!registeredViews.Contains(newView))
return;
void GotFocusEvent(object sender, EventArgs e)
{
if (wasChangedExternally) {
wasChangedExternally = false;
string message = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.TextEditorDisplayBinding.FileAlteredMessage}", new string[,] {{"File", Path.GetFullPath(fileName)}});
if ((AutoLoadExternalChangesOption && viewContent.IsDirty == false)
|| MessageBox.Show(message,
StringParser.Parse("${res:MainWindow.DialogName}"),
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
if (File.Exists(fileName)) {
viewContent.Load(fileName);
}
} else {
viewContent.IsDirty = true;
}
}
}
*/
SwitchedToView(newView);
}
#endregion
}
}

Loading…
Cancel
Save