Browse Source

Add IsDirty logic and CanSaveWithEncoding() to TextDocumentFileModelProvider.

filemodels
Daniel Grunwald 12 years ago
parent
commit
157a745ba0
  1. 57
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs
  2. 48
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  3. 4
      src/Main/Base/Project/Src/Commands/FileCommands.cs
  4. 6
      src/Main/Base/Project/Workbench/File/BinaryFileModelProvider.cs
  5. 5
      src/Main/Base/Project/Workbench/File/DocumentFileModelInfo.cs
  6. 19
      src/Main/Base/Project/Workbench/File/IFileModelProvider.cs
  7. 4
      src/Main/Base/Project/Workbench/File/IFileService.cs
  8. 42
      src/Main/Base/Project/Workbench/File/OpenedFile.cs
  9. 98
      src/Main/Base/Project/Workbench/File/TextDocumentFileModelProvider.cs
  10. 4
      src/Main/Base/Project/Workbench/File/XDocumentFileModelProvider.cs
  11. 2
      src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs
  12. 8
      src/Main/SharpDevelop/Workbench/FileService.cs
  13. 6
      src/Main/SharpDevelop/Workbench/FileServiceOpenedFile.cs

57
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs

@ -77,26 +77,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -77,26 +77,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
return ProjectService.GetFileFilters().Any(f => f.ContainsExtension(filetype)) ||
IconService.HasImageForFile(filetype);
}
void codeEditor_Document_UndoStack_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (!isLoading)
PrimaryFile.IsDirty = !codeEditor.Document.UndoStack.IsOriginalFile;
}
void PrimaryFile_IsDirtyChanged(object sender, EventArgs e)
{
var document = codeEditor.Document;
if (document != null) {
var undoStack = document.UndoStack;
if (this.PrimaryFile.IsDirty) {
if (undoStack.IsOriginalFile)
undoStack.DiscardOriginalFileMarker();
} else {
undoStack.MarkAsOriginalFile();
}
}
}
public override object Control {
get { return codeEditor; }
@ -106,41 +86,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -106,41 +86,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
get { return codeEditor.PrimaryTextEditor.TextArea; }
}
public override void Save(OpenedFile file, Stream stream)
{
if (file != PrimaryFile)
return;
if (codeEditor.CanSaveWithCurrentEncoding()) {
codeEditor.Save(stream);
} else {
int r = MessageService.ShowCustomDialog(
"${res:Dialog.Options.IDEOptions.TextEditor.General.FontGroupBox.FileEncodingGroupBox}",
StringParser.Parse("${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss}",
new StringTagPair("encoding", codeEditor.Encoding.EncodingName)),
0, -1,
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.UseUTF8}",
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.Continue}");
if (r == 1) {
// continue saving with data loss
MemoryStream ms = new MemoryStream();
codeEditor.Save(ms);
ms.Position = 0;
ms.WriteTo(stream);
ms.Position = 0;
// Read back the version we just saved to show the data loss to the user (he'll be able to press Undo).
using (StreamReader reader = new StreamReader(ms, codeEditor.Encoding, false)) {
codeEditor.Document.Text = reader.ReadToEnd();
}
return;
} else {
// unfortunately we don't support cancel within IViewContent.Save, so we'll use the safe choice of UTF-8 instead
codeEditor.Encoding = System.Text.Encoding.UTF8;
codeEditor.Save(stream);
}
}
}
bool isLoading;
public override void Load(OpenedFile file, Stream stream)
@ -261,8 +206,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -261,8 +206,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
if (trackedFeature != null)
trackedFeature.EndTracking();
if (PrimaryFile != null)
this.PrimaryFile.IsDirtyChanged -= PrimaryFile_IsDirtyChanged;
base.Dispose();
BookmarksDetach();
codeEditor.Dispose();

48
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -281,29 +281,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -281,29 +281,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
/// <summary>
/// Use fixed encoding for loading.
/// </summary>
public bool UseFixedEncoding { get; set; }
public Encoding Encoding {
get { return primaryTextEditor.Encoding; }
set { primaryTextEditor.Encoding = value; }
}
/// <summary>
/// Gets if the document can be saved with the current encoding without losing data.
/// </summary>
public bool CanSaveWithCurrentEncoding()
{
Encoding encoding = this.Encoding;
if (encoding == null || FileReader.IsUnicode(encoding))
return true;
// not a unicode codepage
string text = document.Text;
return encoding.GetString(encoding.GetBytes(text)) == text;
}
// always use primary text editor for loading/saving
// (the file encoding is stored only there)
public void Load(Stream stream)
@ -325,31 +302,6 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -325,31 +302,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
NewLineConsistencyCheck.StartConsistencyCheck(this);
}
bool documentFirstLoad = true;
bool clearUndoStackOnSwitch = true;
/// <summary>
/// Gets/Sets whether to clear the undo stack when reloading the document.
/// The default is true.
/// http://community.sharpdevelop.net/forums/t/15816.aspx
/// </summary>
public bool ClearUndoStackOnSwitch {
get { return clearUndoStackOnSwitch; }
set { clearUndoStackOnSwitch = value; }
}
void ReloadDocument(TextDocument document, string newContent)
{
var diff = new MyersDiffAlgorithm(new StringSequence(document.Text), new StringSequence(newContent));
document.Replace(0, document.TextLength, newContent, diff.GetEdits().ToOffsetChangeMap());
if (this.ClearUndoStackOnSwitch || documentFirstLoad)
document.UndoStack.ClearAll();
if (documentFirstLoad)
documentFirstLoad = false;
}
public event EventHandler LoadedFileContent;
public void Save(Stream stream)

4
src/Main/Base/Project/Src/Commands/FileCommands.cs

@ -110,7 +110,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -110,7 +110,7 @@ namespace ICSharpCode.SharpDevelop.Commands
if (File.Exists(file.FileName) && (File.GetAttributes(file.FileName) & attr) != 0) {
SaveFileAs.Save(file);
} else {
FileUtility.ObservedSave(new NamedFileOperationDelegate(file.SaveToDisk), file.FileName, FileErrorPolicy.ProvideAlternative);
FileUtility.ObservedSave(fn => file.SaveToDisk(fn, FileSaveOptions.AllowUserInteraction), file.FileName, FileErrorPolicy.ProvideAlternative);
}
}
}
@ -194,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -194,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Commands
if (!FileService.CheckFileName(fileName)) {
return;
}
if (FileUtility.ObservedSave(new NamedFileOperationDelegate(file.SaveToDisk), fileName) == FileOperationResult.OK) {
if (FileUtility.ObservedSave(fn => file.SaveToDisk(fn, FileSaveOptions.AllowUserInteraction), fileName) == FileOperationResult.OK) {
SD.FileService.RecentOpen.AddRecentFile(fileName);
MessageService.ShowMessage(fileName, "${res:ICSharpCode.SharpDevelop.Commands.SaveFile.FileSaved}");
}

6
src/Main/Base/Project/Workbench/File/BinaryFileModelProvider.cs

@ -29,13 +29,13 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -29,13 +29,13 @@ namespace ICSharpCode.SharpDevelop.Workbench
return new OnDiskBinaryModel(file);
}
public void Save(OpenedFile file, IBinaryFileModel model)
public void Save(OpenedFile file, IBinaryFileModel model, FileSaveOptions options)
{
SaveCopyAs(file, model, file.FileName);
SaveCopyAs(file, model, file.FileName, options);
file.ReplaceModel(this, model, ReplaceModelMode.SetAsValid); // remove dirty flag
}
public void SaveCopyAs(OpenedFile file, IBinaryFileModel model, FileName outputFileName)
public void SaveCopyAs(OpenedFile file, IBinaryFileModel model, FileName outputFileName, FileSaveOptions options)
{
var onDisk = model as OnDiskBinaryModel;
if (onDisk != null) {

5
src/Main/Base/Project/Workbench/File/DocumentFileModelInfo.cs

@ -16,6 +16,11 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -16,6 +16,11 @@ namespace ICSharpCode.SharpDevelop.Workbench
this.Encoding = SD.FileService.DefaultFileEncoding;
}
/// <summary>
/// Gets whether the model is (re)loading.
/// </summary>
internal bool isLoading;
/// <summary>
/// Gets whether the model is stale.
/// </summary>

19
src/Main/Base/Project/Workbench/File/IFileModelProvider.cs

@ -6,6 +6,21 @@ using ICSharpCode.Core; @@ -6,6 +6,21 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Workbench
{
[Flags]
public enum FileSaveOptions
{
None = 0,
/// <summary>
/// Allows displaying modal dialogs during the save operation.
/// For example, the text document file model may prompt the user on data loss due to the choice of encoding.
/// </summary>
AllowUserInteraction = 1,
/// <summary>
/// The save operation was triggered by a GetModel() call.
/// </summary>
SaveForGetModel = 2,
}
/// <summary>
/// Interface that deals with loading and saving OpenedFile model instances.
/// Pre-defined model providers are available in the <see cref="FileModels"/> class.
@ -31,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -31,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// lower-level models, this is done by marking that lower-level model as dirty.
/// In other cases, the provider may have to explicitly remove the dirty flag from the model.
/// </summary>
void Save(OpenedFile file, T model);
void Save(OpenedFile file, T model, FileSaveOptions options);
/// <summary>
/// Saves a file model to disk. This method may by-pass lower-level models (such as FileModels.Binary) and directly write to disk.
@ -39,7 +54,7 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -39,7 +54,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// However, transferring the dirty flag to a lower-level model is allowed.
/// </summary>
/// <exception cref="System.IO.IOException">Error saving the file.</exception>
void SaveCopyAs(OpenedFile file, T model, FileName outputFileName);
void SaveCopyAs(OpenedFile file, T model, FileName outputFileName, FileSaveOptions options);
/// <summary>
/// Gets whether this provider can load from the specified other provider.

4
src/Main/Base/Project/Workbench/File/IFileService.cs

@ -45,6 +45,10 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -45,6 +45,10 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// (in that case, other changes from the view may be saved as well).
/// </summary>
SaveToDisk = 2,
/// <summary>
/// Whether to allow user interaction in the model load+save operations.
/// </summary>
AllowUserInteraction = 4,
}
/// <summary>

42
src/Main/Base/Project/Workbench/File/OpenedFile.cs

@ -40,6 +40,11 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -40,6 +40,11 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// Returns null if the model is not already loaded, or if it is stale and the AllowStale option isn't in use.
/// </summary>
DoNotLoad = 2,
/// <summary>
/// Allows showing modal dialogs during the GetModel() call.
/// For example, the previous model might ask the user details on how to save.
/// </summary>
AllowUserInteraction = 4,
}
/// <summary>
@ -73,8 +78,8 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -73,8 +78,8 @@ namespace ICSharpCode.SharpDevelop.Workbench
public abstract object Provider { get; }
public abstract void Save(OpenedFile file);
public abstract void SaveCopyAs(OpenedFile file, FileName outputFileName);
public abstract void Save(OpenedFile file, FileSaveOptions options);
public abstract void SaveCopyAs(OpenedFile file, FileName outputFileName, FileSaveOptions options);
public abstract void NotifyRename(OpenedFile file, FileName oldName, FileName newName);
public abstract void NotifyStale(OpenedFile file);
public abstract void NotifyUnloaded(OpenedFile file);
@ -95,14 +100,14 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -95,14 +100,14 @@ namespace ICSharpCode.SharpDevelop.Workbench
public override object Provider { get { return provider; } }
public override void Save(OpenedFile file)
public override void Save(OpenedFile file, FileSaveOptions options)
{
provider.Save(file, Model);
provider.Save(file, Model, options);
}
public override void SaveCopyAs(OpenedFile file, FileName outputFileName)
public override void SaveCopyAs(OpenedFile file, FileName outputFileName, FileSaveOptions options)
{
provider.SaveCopyAs(file, Model, outputFileName);
provider.SaveCopyAs(file, Model, outputFileName, options);
}
public override void NotifyRename(OpenedFile file, FileName oldName, FileName newName)
@ -221,25 +226,25 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -221,25 +226,25 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// </summary>
/// <remarks>If the file is saved successfully, the dirty flag will be cleared (the dirty model becomes valid instead).</remarks>
/// <exception cref="InvalidOperationException">The file is untitled.</exception>
public void SaveToDisk()
public void SaveToDisk(FileSaveOptions options)
{
CheckDisposed();
if (IsUntitled)
throw new InvalidOperationException("Cannot save an untitled file to disk.");
SaveToDisk(this.FileName);
SaveToDisk(this.FileName, options);
}
/// <summary>
/// Changes the file name, and saves the file to disk.
/// </summary>
/// <remarks>If the file is saved successfully, the dirty flag will be cleared (the dirty model becomes valid instead).</remarks>
public virtual void SaveToDisk(FileName fileName)
public virtual void SaveToDisk(FileName fileName, FileSaveOptions options)
{
CheckDisposed();
bool safeSaving = SD.FileService.SaveUsingTemporaryFile && SD.FileSystem.FileExists(fileName);
FileName saveAs = safeSaving ? FileName.Create(fileName + ".bak") : fileName;
SaveCopyTo(saveAs);
SaveCopyTo(saveAs, options);
if (safeSaving) {
DateTime creationTime = File.GetCreationTimeUtc(fileName);
File.Delete(fileName);
@ -262,24 +267,23 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -262,24 +267,23 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// <summary>
/// Saves a copy of the file to disk. Does not change the name of the OpenedFile to the specified file name, and does not reset the dirty flag.
/// </summary>
public virtual void SaveCopyAs(FileName fileName)
public virtual void SaveCopyAs(FileName fileName, FileSaveOptions options)
{
CheckDisposed();
SaveCopyTo(fileName);
SaveCopyTo(fileName, options);
}
void SaveCopyTo(FileName outputFileName)
void SaveCopyTo(FileName outputFileName, FileSaveOptions options)
{
preventLoading = true;
try {
var entry = PickValidEntry();
if (entry != null) {
entry.SaveCopyAs(this, outputFileName);
entry.SaveCopyAs(this, outputFileName, options);
} else if (outputFileName != this.FileName) {
SD.FileSystem.CopyFile(this.FileName, outputFileName, true);
}
}
finally {
} finally {
preventLoading = false;
}
}
@ -323,7 +327,10 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -323,7 +327,10 @@ namespace ICSharpCode.SharpDevelop.Workbench
try {
// Before we can load the requested model, save the dirty model (if necessary):
while (dirtyEntry != null && dirtyEntry.NeedsSaveForLoadInto(modelProvider)) {
dirtyEntry.Save(this);
var saveOptions = FileSaveOptions.SaveForGetModel;
if ((options & GetModelOptions.AllowUserInteraction) != 0)
saveOptions |= FileSaveOptions.AllowUserInteraction;
dirtyEntry.Save(this, saveOptions);
// re-fetch entry because it's possible that it was created/replaced/unloaded
entry = GetEntry(modelProvider);
// if the entry was made valid by the save operation, return it directly
@ -497,7 +504,6 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -497,7 +504,6 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// <summary>
/// Gets the reference count of the OpenedFile.
/// This is used for the IFileService.UpdateFileModel() implementation.
/// </summary>
public int ReferenceCount {
get { return referenceCount; }

98
src/Main/Base/Project/Workbench/File/TextDocumentFileModelProvider.cs

@ -10,6 +10,7 @@ using System.Text; @@ -10,6 +10,7 @@ using System.Text;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop.Widgets.MyersDiff;
namespace ICSharpCode.SharpDevelop.Workbench
@ -30,17 +31,46 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -30,17 +31,46 @@ namespace ICSharpCode.SharpDevelop.Workbench
if (document != null) {
// Reload document
var diff = new MyersDiffAlgorithm(new StringSequence(document.Text), new StringSequence(textContent));
document.Replace(0, document.TextLength, textContent, ToOffsetChangeMap(diff.GetEdits()));
document.UndoStack.ClearAll();
info.IsStale = false;
info.isLoading = true;
try {
document.Replace(0, document.TextLength, textContent, ToOffsetChangeMap(diff.GetEdits()));
document.UndoStack.ClearAll();
info.IsStale = false;
} finally {
info.isLoading = false;
}
} else {
document = new TextDocument(textContent);
document.TextChanged += delegate { file.MakeDirty(this); };
document.TextChanged += delegate { UpdateFileIsDirty(document, file, info); };
document.GetRequiredService<IServiceContainer>().AddService(typeof(DocumentFileModelInfo), info);
}
file.IsDirtyChanged += delegate { UpdateUndoStackIsOriginalFile(file, document); };
UpdateUndoStackIsOriginalFile(file, document);
return document;
}
static void UpdateUndoStackIsOriginalFile(ICanBeDirty file, TextDocument document)
{
if (file.IsDirty) {
document.UndoStack.DiscardOriginalFileMarker();
} else {
document.UndoStack.MarkAsOriginalFile();
}
}
void UpdateFileIsDirty(TextDocument document, OpenedFile file, DocumentFileModelInfo info)
{
if (!info.isLoading) {
// Set dirty flag on OpenedFile according to UndoStack.IsOriginalFile
if (document.UndoStack.IsOriginalFile && file.IsDirty) {
// reset dirty marker
file.ReplaceModel(this, document, ReplaceModelMode.SetAsValid);
} else if (!document.UndoStack.IsOriginalFile) {
file.MakeDirty(this);
}
}
}
OffsetChangeMap ToOffsetChangeMap(IEnumerable<Edit> edits)
{
var map = new OffsetChangeMap();
@ -57,27 +87,73 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -57,27 +87,73 @@ namespace ICSharpCode.SharpDevelop.Workbench
return map;
}
public void Save(OpenedFile file, TextDocument model)
public void Save(OpenedFile file, TextDocument model, FileSaveOptions options)
{
MemoryStream ms = new MemoryStream();
SaveTo(ms, model);
file.ReplaceModel(FileModels.Binary, new BinaryFileModel(ms.ToArray()));
SaveTo(ms, model, options);
file.ReplaceModel(FileModels.Binary, new BinaryFileModel(ms.ToArray()), ReplaceModelMode.TransferDirty);
}
public void SaveCopyAs(OpenedFile file, TextDocument model, FileName outputFileName)
public void SaveCopyAs(OpenedFile file, TextDocument model, FileName outputFileName, FileSaveOptions options)
{
using (Stream s = SD.FileSystem.OpenWrite(outputFileName)) {
SaveTo(s, model);
SaveTo(s, model, options);
}
}
static void SaveTo(Stream s, TextDocument model)
static void SaveTo(Stream stream, TextDocument model, FileSaveOptions options)
{
using (StreamWriter w = new StreamWriter(s, model.GetFileModelInfo().Encoding)) {
var info = model.GetFileModelInfo();
if (!CanSaveWithEncoding(model, info.Encoding)) {
if (ConfirmSaveWithDataLoss(info.Encoding, options)) {
// continue saving with data loss
MemoryStream ms = new MemoryStream();
using (StreamWriter w = new StreamWriter(ms, info.Encoding)) {
model.WriteTextTo(w);
}
ms.Position = 0;
ms.WriteTo(stream);
ms.Position = 0;
// Read back the version we just saved to show the data loss to the user (he'll be able to press Undo).
using (StreamReader reader = new StreamReader(ms, info.Encoding, false)) {
model.Text = reader.ReadToEnd();
}
return;
} else {
info.Encoding = new UTF8Encoding(false);
}
}
using (StreamWriter w = new StreamWriter(stream, info.Encoding)) {
model.WriteTextTo(w);
}
}
/// <summary>
/// Gets if the document can be saved with the current encoding without losing data.
/// </summary>
static bool CanSaveWithEncoding(IDocument document, Encoding encoding)
{
if (encoding == null || FileReader.IsUnicode(encoding))
return true;
// not a unicode codepage
string text = document.Text;
return encoding.GetString(encoding.GetBytes(text)) == text;
}
static bool ConfirmSaveWithDataLoss(Encoding encoding, FileSaveOptions options)
{
if ((options & FileSaveOptions.AllowUserInteraction) == 0)
return false; // default to UTF-8 if we can't ask the user
int r = MessageService.ShowCustomDialog(
"${res:Dialog.Options.IDEOptions.TextEditor.General.FontGroupBox.FileEncodingGroupBox}",
StringParser.Parse("${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss}",
new StringTagPair("encoding", encoding.EncodingName)),
0, -1,
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.UseUTF8}",
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.Continue}");
return r == 1;
}
bool IFileModelProvider<TextDocument>.CanLoadFrom<U>(IFileModelProvider<U> otherProvider)
{
return otherProvider == FileModels.Binary || FileModels.Binary.CanLoadFrom(otherProvider);

4
src/Main/Base/Project/Workbench/File/XDocumentFileModelProvider.cs

@ -22,14 +22,14 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -22,14 +22,14 @@ namespace ICSharpCode.SharpDevelop.Workbench
return document;
}
public void Save(OpenedFile file, XDocument model)
public void Save(OpenedFile file, XDocument model, FileSaveOptions options)
{
MemoryStream ms = new MemoryStream();
model.Save(ms, SaveOptions.DisableFormatting);
file.ReplaceModel(FileModels.Binary, new BinaryFileModel(ms.ToArray()));
}
public void SaveCopyAs(OpenedFile file, XDocument model, FileName outputFileName)
public void SaveCopyAs(OpenedFile file, XDocument model, FileName outputFileName, FileSaveOptions options)
{
model.Save(outputFileName, SaveOptions.DisableFormatting);
}

2
src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs

@ -532,7 +532,7 @@ namespace ICSharpCode.SharpDevelop.Templates @@ -532,7 +532,7 @@ namespace ICSharpCode.SharpDevelop.Templates
file.ReplaceModel(FileModels.Binary, new BinaryFileModel(data));
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
file.SaveToDisk();
file.SaveToDisk(FileSaveOptions.None);
if (project != null)
AddTemplateFileToProject(project, newFile, fileName);

8
src/Main/SharpDevelop/Workbench/FileService.cs

@ -256,19 +256,21 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -256,19 +256,21 @@ namespace ICSharpCode.SharpDevelop.Workbench
public void UpdateFileModel<T>(FileName fileName, IFileModelProvider<T> modelProvider, Action<T> action, FileUpdateOptions options = FileUpdateOptions.None) where T : class
{
bool interactive = (options & FileUpdateOptions.AllowUserInteraction) == FileUpdateOptions.AllowUserInteraction;
OpenedFile file = CreateOpenedFile(fileName);
try {
T model = file.GetModel(modelProvider);
T model = file.GetModel(modelProvider, interactive ? GetModelOptions.AllowUserInteraction : GetModelOptions.None);
action(model);
FileSaveOptions saveOptions = interactive ? FileSaveOptions.AllowUserInteraction : FileSaveOptions.None;
if ((options & FileUpdateOptions.SaveToDisk) == FileUpdateOptions.SaveToDisk) {
file.SaveToDisk();
file.SaveToDisk(saveOptions);
}
if (!IsOpen(fileName) && file.IsDirty) {
// The file is not open in a view, but we need to store our changes somewhere:
if ((options & FileUpdateOptions.OpenViewIfNoneExists) != 0) {
OpenFile(fileName, false);
} else {
file.SaveToDisk();
file.SaveToDisk(saveOptions);
}
}
} finally {

6
src/Main/SharpDevelop/Workbench/FileServiceOpenedFile.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -58,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
fileChangeWatcher = null;
}
if (wasDirty) {
if (wasDirty && SD.ParserService.GetExistingUnresolvedFile(this.FileName) != null) {
// We discarded some information when closing the file,
// so we need to re-parse it.
if (SD.FileSystem.FileExists(this.FileName))
@ -68,12 +68,12 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -68,12 +68,12 @@ namespace ICSharpCode.SharpDevelop.Workbench
}
}
public override void SaveToDisk(FileName fileName)
public override void SaveToDisk(FileName fileName, FileSaveOptions options)
{
try {
if (fileChangeWatcher != null)
fileChangeWatcher.Enabled = false;
base.SaveToDisk(fileName);
base.SaveToDisk(fileName, options);
} finally {
if (fileChangeWatcher != null)
fileChangeWatcher.Enabled = true;

Loading…
Cancel
Save