diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2019-06-04 22:40:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-04 22:40:09 +0300 |
commit | 8f170d9469ccbd51acdf938d5fc8a6689b7678cc (patch) | |
tree | 6d9ee4d8dba03b9f62731b4725bfca8d30fe4159 /main/src | |
parent | bd21705135a5b0cf850954190e3666a8b7e9b7a3 (diff) | |
parent | 046482870c9040954dd3b9296d719e26c1216eec (diff) |
Merge pull request #7779 from mono/fix-825629
Fix mime type assignment issues in FileModel
Diffstat (limited to 'main/src')
5 files changed, 71 insertions, 15 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentModel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentModel.cs index 18e0b74522..e05ed9f1c2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentModel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/DocumentModel.cs @@ -103,14 +103,20 @@ namespace MonoDevelop.Ide.Gui.Documents public void CreateNew () { + InitializeNew (); + ModelRepresentation.CreateNew (); + } + + protected void InitializeNew () + { if (IsLoaded) throw new InvalidOperationException ("Model already loaded"); if (Data.IsLinked) throw new InvalidOperationException ("Model already linked"); isNew = true; - ModelRepresentation.CreateNew (); } + public bool IsNew { get { CheckInitialized (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileDocumentController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileDocumentController.cs index fc2801d171..2ecfd021c1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileDocumentController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileDocumentController.cs @@ -110,7 +110,7 @@ namespace MonoDevelop.Ide.Gui.Documents if (!typeof (FileModel).IsAssignableFrom (FileModelType)) throw new InvalidOperationException ("Invalid file model type: " + FileModelType); var fileModel = (FileModel)Activator.CreateInstance (FileModelType); - fileModel.CreateNew (); + fileModel.CreateNew (fileDescriptor.FilePath, fileDescriptor.MimeType); await fileModel.SetContent (fileDescriptor.Content); if (fileDescriptor.Encoding != null && fileModel is TextFileModel textFileModel) textFileModel.Encoding = fileDescriptor.Encoding; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileModel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileModel.cs index 2d0b324dc6..b2c3ed6f24 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileModel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/FileModel.cs @@ -41,9 +41,9 @@ namespace MonoDevelop.Ide.Gui.Documents { } - public string MimeType { get; set; } + public string MimeType => IsLoaded ? GetRepresentation<FileModelRepresentation> ().MimeType : null; - public FilePath FilePath => Id != null ? (FilePath)Id : FilePath.Null; + public FilePath FilePath => Id != null ? (FilePath) Id : (IsLoaded ? GetRepresentation<FileModelRepresentation> ().FilePath : FilePath.Null); public bool CanWrite { get { @@ -57,6 +57,14 @@ namespace MonoDevelop.Ide.Gui.Documents } } + public void CreateNew (string fileName, string mimeType) + { + InitializeNew (); + var rep = GetRepresentation<FileModelRepresentation> (); + rep.InitUnsaved (fileName, mimeType); + rep.CreateNew (); + } + public Task LinkToFile (FilePath filePath) { if (FilePath != filePath) @@ -70,10 +78,10 @@ namespace MonoDevelop.Ide.Gui.Documents await UnlinkFromId (); } - public Task SaveAs (FilePath filePath) + public async Task SaveAs (FilePath filePath) { - LinkToFile (filePath); - return Save (); + await LinkToFile (filePath); + await Save (); } /// <summary> @@ -99,9 +107,20 @@ namespace MonoDevelop.Ide.Gui.Documents protected abstract class FileModelRepresentation : ModelRepresentation { - public FilePath FilePath => Id != null ? (FilePath)Id : FilePath.Null; + FilePath unsavedFilePath; + + public FilePath FilePath => Id != null ? (FilePath)Id : unsavedFilePath; public string MimeType { get; set; } + internal void InitUnsaved (FilePath filePath, string mimeType) + { + unsavedFilePath = filePath; + if (mimeType != null) + MimeType = mimeType; + else if (!filePath.IsNullOrEmpty) + MimeType = Runtime.PeekService<DesktopService> ()?.GetMimeTypeForUri (filePath); + } + public async Task SetContent (Stream content) { try { @@ -128,6 +147,11 @@ namespace MonoDevelop.Ide.Gui.Documents } else throw new InvalidOperationException ($"Can't copy data from model of type {other.GetType ()} into a model of type {GetType ()}"); } + + protected override async Task OnIdChanged () + { + MimeType = (await Runtime.GetService<DesktopService> ()).GetMimeTypeForUri (FilePath); + } } class InternalFileModelRepresentation : FileModelRepresentation diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/ModelRepresentation.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/ModelRepresentation.cs index bdbde45d4c..8ca0506274 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/ModelRepresentation.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/ModelRepresentation.cs @@ -68,6 +68,7 @@ namespace MonoDevelop.Ide.Gui.Documents { try { await WaitHandle.WaitAsync (); + await CheckIdChange (); if (IsLoaded) return; if (DocumentModelData.IsLinked) @@ -96,6 +97,7 @@ namespace MonoDevelop.Ide.Gui.Documents { try { await WaitHandle.WaitAsync (); + await CheckIdChange (); await OnLoad (); IsLoaded = true; HasUnsavedChanges = false; @@ -108,6 +110,7 @@ namespace MonoDevelop.Ide.Gui.Documents { try { await WaitHandle.WaitAsync (); + await CheckIdChange (); await OnSave (); HasUnsavedChanges = false; } finally { @@ -138,6 +141,25 @@ namespace MonoDevelop.Ide.Gui.Documents protected abstract void OnCreateNew (); + /// <summary> + /// Invoked just before a load or save operation when the Id of a model has changed + /// </summary> + protected virtual Task OnIdChanged () + { + return Task.CompletedTask; + } + + object id; + + Task CheckIdChange () + { + if (id != Id) { + id = Id; + return OnIdChanged (); + } else + return Task.CompletedTask; + } + protected abstract Task OnLoad (); protected abstract Task OnSave (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs index 5b3e7db3c6..59f3193212 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Documents/TextBufferFileModel.cs @@ -66,8 +66,7 @@ namespace MonoDevelop.Ide.Gui.Documents protected override async Task OnLoad () { var text = await TextFileUtility.GetTextAsync (FilePath, CancellationToken.None); - MimeType = (await Runtime.GetService<DesktopService> ()).GetMimeTypeForUri (FilePath); - var contentType = (MimeType == null) ? PlatformCatalog.Instance.TextBufferFactoryService.InertContentType : GetContentTypeFromMimeType (FilePath, MimeType); + var contentType = GetContentTypeFromMimeType (); if (textDocument != null) { // Reloading try { @@ -115,6 +114,10 @@ namespace MonoDevelop.Ide.Gui.Documents protected override Task OnSave () { + var contentType = GetContentTypeFromMimeType (); + if (textDocument.TextBuffer.ContentType != contentType) + textDocument.TextBuffer.ChangeContentType (contentType, null); + // OnLoad is always called before anything else, so the document should be ready textDocument.SaveAs (FilePath, true); cleanReiteratedVersion = textDocument.TextBuffer.CurrentSnapshot.Version.ReiteratedVersionNumber; @@ -126,17 +129,18 @@ namespace MonoDevelop.Ide.Gui.Documents ITextDocument CreateTextDocument (string text) { - var contentType = (MimeType == null) - ? PlatformCatalog.Instance.TextBufferFactoryService.InertContentType - : GetContentTypeFromMimeType (FilePath, MimeType); + var contentType = GetContentTypeFromMimeType (); var buffer = PlatformCatalog.Instance.TextBufferFactoryService.CreateTextBuffer (text, contentType); var doc = PlatformCatalog.Instance.TextDocumentFactoryService.CreateTextDocument (buffer, FilePath.ToString () ?? ""); return doc; } - protected static IContentType GetContentTypeFromMimeType (string filePath, string mimeType) + IContentType GetContentTypeFromMimeType () { - return MimeTypeCatalog.Instance.GetContentTypeForMimeType (mimeType, filePath) + if (MimeType == null) + return PlatformCatalog.Instance.TextBufferFactoryService.InertContentType; + + return MimeTypeCatalog.Instance.GetContentTypeForMimeType (MimeType, FilePath) ?? PlatformCatalog.Instance.ContentTypeRegistryService.GetContentType ("text"); } |