1 using EnvDTE;
2 using Microsoft.VisualStudio;
3 using Microsoft.VisualStudio.Shell;
4 using Microsoft.VisualStudio.Shell.Interop;
5 using System.Linq;
6 
7 namespace LLVM.ClangFormat
8 {
9     // Exposes event sources for IVsRunningDocTableEvents3 events.
10     internal sealed class RunningDocTableEventsDispatcher : IVsRunningDocTableEvents3
11     {
12         private RunningDocumentTable _runningDocumentTable;
13         private DTE _dte;
14 
15         public delegate void OnBeforeSaveHander(object sender, Document document);
16         public event OnBeforeSaveHander BeforeSave;
17 
18         public RunningDocTableEventsDispatcher(Package package)
19         {
20             _runningDocumentTable = new RunningDocumentTable(package);
21             _runningDocumentTable.Advise(this);
22             _dte = (DTE)Package.GetGlobalService(typeof(DTE));
23         }
24 
25         public int OnAfterAttributeChange(uint docCookie, uint grfAttribs)
26         {
27             return VSConstants.S_OK;
28         }
29 
30         public int OnAfterAttributeChangeEx(uint docCookie, uint grfAttribs, IVsHierarchy pHierOld, uint itemidOld, string pszMkDocumentOld, IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew)
31         {
32             return VSConstants.S_OK;
33         }
34 
35         public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
36         {
37             return VSConstants.S_OK;
38         }
39 
40         public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
41         {
42             return VSConstants.S_OK;
43         }
44 
45         public int OnAfterSave(uint docCookie)
46         {
47             return VSConstants.S_OK;
48         }
49 
50         public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
51         {
52             return VSConstants.S_OK;
53         }
54 
55         public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
56         {
57             return VSConstants.S_OK;
58         }
59 
60         public int OnBeforeSave(uint docCookie)
61         {
62             if (BeforeSave != null)
63             {
64                 var document = FindDocumentByCookie(docCookie);
65                 if (document != null) // Not sure why this happens sometimes
66                 {
67                     BeforeSave(this, FindDocumentByCookie(docCookie));
68                 }
69             }
70             return VSConstants.S_OK;
71         }
72 
73         private Document FindDocumentByCookie(uint docCookie)
74         {
75             var documentInfo = _runningDocumentTable.GetDocumentInfo(docCookie);
76             return _dte.Documents.Cast<Document>().FirstOrDefault(doc => doc.FullName == documentInfo.Moniker);
77         }
78     }
79 }
80