Browse Source

Fixed SD2-1136: File changed externally message only appears when SharpDevelop loses focus

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1868 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
0d14714a98
  1. 75
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs
  2. 7
      src/Main/Base/Project/Src/Gui/IWorkbench.cs
  3. 23
      src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs
  4. 170
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

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

@ -45,8 +45,7 @@ namespace ICSharpCode.XmlEditor
public static readonly string CategoryName = "XML"; public static readonly string CategoryName = "XML";
XmlEditorControl xmlEditor = new XmlEditorControl(); XmlEditorControl xmlEditor = new XmlEditorControl();
FileSystemWatcher watcher; TextEditorDisplayBindingWrapper.FileChangeWatcher watcher;
bool wasChangedExternally;
static MessageViewCategory category; static MessageViewCategory category;
string stylesheetFileName; string stylesheetFileName;
XmlTreeView xmlTreeView; XmlTreeView xmlTreeView;
@ -61,7 +60,7 @@ namespace ICSharpCode.XmlEditor
xmlEditor.ActiveTextAreaControl.Caret.CaretModeChanged += CaretModeChanged; xmlEditor.ActiveTextAreaControl.Caret.CaretModeChanged += CaretModeChanged;
xmlEditor.ActiveTextAreaControl.Caret.PositionChanged += CaretChanged; xmlEditor.ActiveTextAreaControl.Caret.PositionChanged += CaretChanged;
xmlEditor.ActiveTextAreaControl.Enter += CaretUpdate; xmlEditor.ActiveTextAreaControl.Enter += CaretUpdate;
((Form)ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench).Activated += GotFocusEvent; watcher = new TextEditorDisplayBindingWrapper.FileChangeWatcher(this);
// Listen for changes to the xml editor properties. // Listen for changes to the xml editor properties.
XmlEditorAddInOptions.PropertyChanged += PropertyChanged; XmlEditorAddInOptions.PropertyChanged += PropertyChanged;
@ -293,7 +292,7 @@ namespace ICSharpCode.XmlEditor
public override void Dispose() public override void Dispose()
{ {
base.Dispose(); base.Dispose();
((Form)ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench).Activated -= new EventHandler(GotFocusEvent); watcher.Dispose();
XmlEditorAddInOptions.PropertyChanged -= PropertyChanged; XmlEditorAddInOptions.PropertyChanged -= PropertyChanged;
XmlSchemaManager.UserSchemaAdded -= new EventHandler(UserSchemaAdded); XmlSchemaManager.UserSchemaAdded -= new EventHandler(UserSchemaAdded);
@ -524,23 +523,20 @@ namespace ICSharpCode.XmlEditor
} }
UpdateFolding(); UpdateFolding();
SetWatcher(); watcher.SetWatcher(fileName);
} }
public override void Save(string fileName) public override void Save(string fileName)
{ {
OnSaving(EventArgs.Empty); OnSaving(EventArgs.Empty);
watcher.Disable();
if (watcher != null) {
watcher.EnableRaisingEvents = false;
}
xmlEditor.SaveFile(fileName); xmlEditor.SaveFile(fileName);
FileName = fileName; FileName = fileName;
TitleName = Path.GetFileName(fileName); TitleName = Path.GetFileName(fileName);
IsDirty = false; IsDirty = false;
SetWatcher(); watcher.SetWatcher(fileName);
OnSaved(new SaveEventArgs(true)); OnSaved(new SaveEventArgs(true));
} }
@ -774,65 +770,6 @@ namespace ICSharpCode.XmlEditor
StatusBarService.SetInsertMode(xmlEditor.ActiveTextAreaControl.Caret.CaretMode == CaretMode.InsertMode); StatusBarService.SetInsertMode(xmlEditor.ActiveTextAreaControl.Caret.CaretMode == CaretMode.InsertMode);
} }
/// <summary>
/// Creates the file system watcher.
/// </summary>
void SetWatcher()
{
try {
if (this.watcher == null) {
this.watcher = new FileSystemWatcher();
this.watcher.Changed += new FileSystemEventHandler(this.OnFileChangedEvent);
} else {
this.watcher.EnableRaisingEvents = false;
}
this.watcher.Path = Path.GetDirectoryName(xmlEditor.FileName);
this.watcher.Filter = Path.GetFileName(xmlEditor.FileName);
this.watcher.NotifyFilter = NotifyFilters.LastWrite;
this.watcher.EnableRaisingEvents = true;
} catch (Exception) {
watcher = null;
}
}
/// <summary>
/// Shows the "File was changed" dialog if the file was
/// changed externally.
/// </summary>
void GotFocusEvent(object sender, EventArgs e)
{
lock (this) {
if (wasChangedExternally) {
wasChangedExternally = false;
string message = StringParser.Parse("${res:ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.TextEditorDisplayBinding.FileAlteredMessage}", new string[,] {{"File", Path.GetFullPath(xmlEditor.FileName)}});
if (MessageService.AskQuestion(message, "${res:MainWindow.DialogName}")) {
Load(xmlEditor.FileName);
} else {
IsDirty = true;
}
}
}
}
void OnFileChangedEvent(object sender, FileSystemEventArgs e)
{
if(e.ChangeType != WatcherChangeTypes.Deleted) {
wasChangedExternally = true;
if (xmlEditor.IsHandleCreated) {
xmlEditor.BeginInvoke(new MethodInvoker(OnFileChangedEventInvoked));
}
}
}
void OnFileChangedEventInvoked()
{
Console.WriteLine("XmlView.OnFileChangedEventInvoked");
if (((Form)ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench).Focused) {
Console.WriteLine("OnFileChangedEventInvoked - Workbench has focus");
GotFocusEvent(this, EventArgs.Empty);
}
}
/// <summary> /// <summary>
/// Gets the xml validation output window. /// Gets the xml validation output window.
/// </summary> /// </summary>

7
src/Main/Base/Project/Src/Gui/IWorkbench.cs

@ -55,6 +55,13 @@ namespace ICSharpCode.SharpDevelop.Gui
set; set;
} }
/// <summary>
/// Gets whether SharpDevelop is the active application in Windows.
/// </summary>
bool IsActiveWindow {
get;
}
/// <summary> /// <summary>
/// Inserts a new <see cref="IViewContent"/> object in the workspace. /// Inserts a new <see cref="IViewContent"/> object in the workspace.
/// </summary> /// </summary>

23
src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs

@ -34,6 +34,8 @@ namespace ICSharpCode.SharpDevelop.Gui
List<PadDescriptor> viewContentCollection = new List<PadDescriptor>(); List<PadDescriptor> viewContentCollection = new List<PadDescriptor>();
List<IViewContent> workbenchContentCollection = new List<IViewContent>(); List<IViewContent> workbenchContentCollection = new List<IViewContent>();
bool isActiveWindow; // Gets whether SharpDevelop is the active application in Windows
bool closeAll = false; bool closeAll = false;
bool fullscreen; bool fullscreen;
@ -78,6 +80,15 @@ namespace ICSharpCode.SharpDevelop.Gui
} }
} }
/// <summary>
/// Gets whether SharpDevelop is the active application in Windows.
/// </summary>
public bool IsActiveWindow {
get {
return isActiveWindow;
}
}
public IWorkbenchLayout WorkbenchLayout { public IWorkbenchLayout WorkbenchLayout {
get { get {
return layout; return layout;
@ -688,5 +699,17 @@ namespace ICSharpCode.SharpDevelop.Gui
public event ViewContentEventHandler ViewOpened; public event ViewContentEventHandler ViewOpened;
public event ViewContentEventHandler ViewClosed; public event ViewContentEventHandler ViewClosed;
public event EventHandler ActiveWorkbenchWindowChanged; public event EventHandler ActiveWorkbenchWindowChanged;
protected override void OnActivated(EventArgs e)
{
isActiveWindow = true;
base.OnActivated(e);
}
protected override void OnDeactivate(EventArgs e)
{
isActiveWindow = false;
base.OnDeactivate(e);
}
} }
} }

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

@ -79,6 +79,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
public class TextEditorDisplayBindingWrapper : AbstractViewContent, IMementoCapable, IPrintable, IEditable, IUndoHandler, IPositionable, ITextEditorControlProvider, IParseInformationListener, IClipboardHandler, IContextHelpProvider public class TextEditorDisplayBindingWrapper : AbstractViewContent, IMementoCapable, IPrintable, IEditable, IUndoHandler, IPositionable, ITextEditorControlProvider, IParseInformationListener, IClipboardHandler, IContextHelpProvider
{ {
public SharpDevelopTextAreaControl textAreaControl = null; public SharpDevelopTextAreaControl textAreaControl = null;
FileChangeWatcher watcher;
public TextEditorControl TextEditorControl { public TextEditorControl TextEditorControl {
get { get {
@ -86,10 +87,86 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
// KSL Start, New lines public sealed class FileChangeWatcher : IDisposable
protected FileSystemWatcher watcher; {
protected bool wasChangedExternally = false; FileSystemWatcher watcher;
// KSL End bool wasChangedExternally = false;
string fileName;
AbstractViewContent viewContent;
public FileChangeWatcher(AbstractViewContent viewContent)
{
this.viewContent = viewContent;
WorkbenchSingleton.MainForm.Activated += GotFocusEvent;
}
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;
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) {
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 (viewContent.IsDirty == false ||
MessageBox.Show(message,
StringParser.Parse("${res:MainWindow.DialogName}"),
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
viewContent.Load(fileName);
} else {
viewContent.IsDirty = true;
}
}
}
}
public bool EnableUndo { public bool EnableUndo {
get { get {
@ -164,7 +241,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{ {
base.OnFileNameChanged(e); base.OnFileNameChanged(e);
textAreaControl.FileName = base.FileName; textAreaControl.FileName = base.FileName;
SetWatcher(); // update file name the watcher looks at watcher.SetWatcher(textAreaControl.FileName); // update file name the watcher looks at
} }
public void Undo() public void Undo()
@ -190,15 +267,8 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
textAreaControl.ActiveTextAreaControl.Caret.CaretModeChanged += new EventHandler(CaretModeChanged); textAreaControl.ActiveTextAreaControl.Caret.CaretModeChanged += new EventHandler(CaretModeChanged);
textAreaControl.ActiveTextAreaControl.Enter += new EventHandler(CaretUpdate); textAreaControl.ActiveTextAreaControl.Enter += new EventHandler(CaretUpdate);
textAreaControl.ActiveTextAreaControl.Caret.PositionChanged += CaretUpdate; textAreaControl.ActiveTextAreaControl.Caret.PositionChanged += CaretUpdate;
watcher = new FileChangeWatcher(this);
// KSL Start, New lines
// textAreaControl.FileNameChanged += new EventHandler(FileNameChangedEvent);
((Form)ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench).Activated += new EventHandler(GotFocusEvent);
// KSL End
} }
// KSL Start, new event handlers
public void ShowHelp() public void ShowHelp()
{ {
@ -225,62 +295,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
} }
} }
protected void SetWatcher()
{
try {
if (this.watcher == null) {
this.watcher = new FileSystemWatcher();
this.watcher.Changed += new FileSystemEventHandler(this.OnFileChangedEvent);
} else {
this.watcher.EnableRaisingEvents = false;
}
this.watcher.Path = Path.GetDirectoryName(textAreaControl.FileName);
this.watcher.Filter = Path.GetFileName(textAreaControl.FileName);
this.watcher.NotifyFilter = NotifyFilters.LastWrite;
this.watcher.EnableRaisingEvents = true;
} catch (Exception) {
if (watcher != null) {
watcher.Dispose();
}
watcher = null;
}
}
protected virtual 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(textAreaControl.FileName)}});
if (IsDirty == false ||
MessageBox.Show(message,
StringParser.Parse("${res:MainWindow.DialogName}"),
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes) {
Load(textAreaControl.FileName);
} else {
IsDirty = true;
}
}
}
void OnFileChangedEvent(object sender, FileSystemEventArgs e)
{
if(e.ChangeType != WatcherChangeTypes.Deleted) {
wasChangedExternally = true;
if (textAreaControl.IsHandleCreated)
textAreaControl.BeginInvoke(new MethodInvoker(OnFileChangedEventInvoked));
}
}
void OnFileChangedEventInvoked()
{
if (((Form)ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench).Focused) {
GotFocusEvent(this, EventArgs.Empty);
}
}
// KSL End
void TextAreaChangedEvent(object sender, DocumentEventArgs e) void TextAreaChangedEvent(object sender, DocumentEventArgs e)
{ {
IsDirty = true; IsDirty = true;
@ -298,13 +312,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
if (this.IsUntitled) { if (this.IsUntitled) {
ParserService.ClearParseInformation(this.UntitledName); ParserService.ClearParseInformation(this.UntitledName);
} }
if (WorkbenchSingleton.MainForm != null) { watcher.Dispose();
WorkbenchSingleton.MainForm.Activated -= new EventHandler(GotFocusEvent);
}
if (this.watcher != null) {
this.watcher.Dispose();
this.watcher = null;
}
textAreaControl.Dispose(); textAreaControl.Dispose();
base.Dispose(); base.Dispose();
} }
@ -318,11 +326,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
public override void Save(string fileName) public override void Save(string fileName)
{ {
OnSaving(EventArgs.Empty); OnSaving(EventArgs.Empty);
// KSL, Start new line watcher.Disable();
if (watcher != null) {
this.watcher.EnableRaisingEvents = false;
}
// KSL End
if (!textAreaControl.CanSaveWithCurrentEncoding()) { if (!textAreaControl.CanSaveWithCurrentEncoding()) {
if (MessageService.AskQuestion("The file cannot be saved with the current encoding " + if (MessageService.AskQuestion("The file cannot be saved with the current encoding " +
@ -341,7 +345,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
TitleName = Path.GetFileName(fileName); TitleName = Path.GetFileName(fileName);
IsDirty = false; IsDirty = false;
SetWatcher(); watcher.SetWatcher(this.FileName);
OnSaved(new SaveEventArgs(true)); OnSaved(new SaveEventArgs(true));
} }
@ -354,7 +358,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
FileName = fileName; FileName = fileName;
TitleName = Path.GetFileName(fileName); TitleName = Path.GetFileName(fileName);
IsDirty = false; IsDirty = false;
SetWatcher(); watcher.SetWatcher(fileName);
foreach (Bookmarks.SDBookmark mark in Bookmarks.BookmarkManager.GetBookmarks(fileName)) { foreach (Bookmarks.SDBookmark mark in Bookmarks.BookmarkManager.GetBookmarks(fileName)) {
mark.Document = textAreaControl.Document; mark.Document = textAreaControl.Document;
textAreaControl.Document.BookmarkManager.Marks.Add(mark); textAreaControl.Document.BookmarkManager.Marks.Add(mark);

Loading…
Cancel
Save