public Document(IWorkbenchWindow window) { Counters.OpenDocuments++; LastTimeActive = DateTime.Now; this.window = window; window.Closed += OnClosed; window.ActiveViewContentChanged += OnActiveViewContentChanged; if (IdeApp.Workspace != null) { IdeApp.Workspace.ItemRemovedFromSolution += OnEntryRemoved; } if (window.ViewContent.Project != null) { window.ViewContent.Project.Modified += HandleProjectModified; } window.ViewsChanged += HandleViewsChanged; window.ViewContent.ContentNameChanged += OnContentNameChanged; MonoDevelopWorkspace.LoadingFinished += ReloadAnalysisDocumentHandler; DocumentRegistry.Add(this); }
internal void Dispose() { DocumentRegistry.Remove(this); callbackRegistration?.Dispose(); var workspace = Runtime.PeekService <RootWorkspace> (); if (workspace != null) { workspace.ItemRemovedFromSolution -= OnEntryRemoved; } UnsubscribeControllerEvents(); window.SetRootView(null); view.IsRoot = false; view.Dispose(); // This will also dispose the controller window = null; contentCallbackRegistry = null; contentActiveViewCallbackRegistry = null; }
protected override void OnDispose(bool disposing) { if (IsDisposed) { return; } DocumentRegistry.Remove(this); UnsubscribeAnalysisDocument(); UnsubscribeRoslynWorkspace(); UnloadAdhocProject(); if (window is SdiWorkspaceWindow) { ((SdiWorkspaceWindow)window).DetachFromPathedDocument(); } window.Closed -= OnClosed; window.ActiveViewContentChanged -= OnActiveViewContentChanged; if (IdeApp.Workspace != null) { IdeApp.Workspace.ItemRemovedFromSolution -= OnEntryRemoved; } // Unsubscribe project events if (window.ViewContent.Project != null) { window.ViewContent.Project.Modified -= HandleProjectModified; } window.ViewsChanged -= HandleViewsChanged; window.ViewContent.ContentNameChanged -= OnContentNameChanged; MonoDevelopWorkspace.LoadingFinished -= ReloadAnalysisDocumentHandler; window = null; parsedDocument = null; views = null; viewsRO = null; base.OnDispose(disposing); }
internal Document(DocumentManager documentManager, IShell shell, DocumentController controller, DocumentControllerDescription controllerDescription, IWorkbenchWindow window) { Counters.OpenDocuments++; this.shell = shell; this.documentManager = documentManager; this.documentControllerDescription = controllerDescription; this.controller = controller; controller.Document = this; callbackRegistration = documentManager.ServiceProvider.WhenServiceInitialized <RootWorkspace> (s => { s.ItemRemovedFromSolution += OnEntryRemoved; callbackRegistration = null; }); this.window = window; window.Document = this; LastTimeActive = DateTime.Now; this.window.CloseRequested += Window_CloseRequested; SubscribeControllerEvents(); DocumentRegistry.Add(this); }
async Task SaveTask() { // suspend type service "check all file loop" since we have already a parsed document. // Or at least one that updates "soon". try { // Freeze the file change events. There can be several such events, and sending them all together // is more efficient FileService.FreezeEvents(); if (Window.ViewContent.IsViewOnly || !Window.ViewContent.IsDirty) { return; } if (!Window.ViewContent.IsFile) { await Window.ViewContent.Save(); return; } if (IsUntitled) { await SaveAs(); } else { try { FileService.RequestFileEdit((FilePath)Window.ViewContent.ContentName, true); } catch (Exception ex) { MessageService.ShowError(GettextCatalog.GetString("The file could not be saved."), ex.Message, ex); } FileAttributes attr = FileAttributes.ReadOnly | FileAttributes.Directory | FileAttributes.Offline | FileAttributes.System; if (!File.Exists((string)Window.ViewContent.ContentName) || (File.GetAttributes((string)window.ViewContent.ContentName) & attr) != 0) { await SaveAs(); } else { string fileName = Window.ViewContent.ContentName; // save backup first if (IdeApp.Preferences.CreateFileBackupCopies) { await Window.ViewContent.Save(fileName + "~"); FileService.NotifyFileChanged(fileName + "~"); } DocumentRegistry.SkipNextChange(fileName); await Window.ViewContent.Save(fileName); FileService.NotifyFileChanged(fileName); OnSaved(EventArgs.Empty); } } } finally { // Send all file change notifications FileService.ThawEvents(); // Set the file time of the current document after the file time of the written file, to prevent double file updates. // Note that the parsed document may be overwritten by a background thread to a more recent one. var doc = parsedDocument; if (doc != null) { string fileName = Window.ViewContent.ContentName; try { // filename could be null if the user cancelled SaveAs and this is a new & unsaved file if (fileName != null) { doc.LastWriteTimeUtc = File.GetLastWriteTimeUtc(fileName); } } catch (Exception e) { doc.LastWriteTimeUtc = DateTime.UtcNow; LoggingService.LogWarning("Exception while getting the write time from " + fileName, e); } } } }
async Task SaveTask() { // suspend type service "check all file loop" since we have already a parsed document. // Or at least one that updates "soon". var fileController = controller as FileDocumentController; try { // Freeze the file change events. There can be several such events, and sending them all together // is more efficient FileService.FreezeEvents(); if (controller.IsViewOnly || !controller.HasUnsavedChanges) { return; } if (fileController == null) { await controller.Save(); return; } if (IsNewDocument) { await SaveAs(); } else { var fileName = fileController.FilePath; try { FileService.RequestFileEdit(fileName, true); } catch (Exception ex) { MessageService.ShowError(GettextCatalog.GetString("The file could not be saved."), ex.Message, ex); } FileAttributes attr = FileAttributes.ReadOnly | FileAttributes.Directory | FileAttributes.Offline | FileAttributes.System; if (!File.Exists(fileName) || (File.GetAttributes(fileName) & attr) != 0) { await SaveAs(); } else { var allFiles = controller.GetDocumentFiles().ToList(); foreach (var file in allFiles) { DocumentRegistry.SkipNextChange(file); } await controller.Save(); if (IdeApp.Preferences.CreateFileBackupCopies) { foreach (var file in allFiles) { try { File.Copy(file, file + "~"); } catch (Exception ex) { LoggingService.LogError("Backup copy could not be created", ex); } } } // Force a change notification. This is needed for FastCheckNeedsBuild to be updated // when saving before a build, for example. FileService.NotifyFilesChanged(allFiles); Saved?.Invoke(this, EventArgs.Empty); } } } finally { // Send all file change notifications FileService.ThawEvents(); } }