예제 #1
0
 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);
 }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
                    }
                }
            }
        }
예제 #6
0
        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();
            }
        }