OLD | NEW |
| (Empty) |
1 /// Copyright (c) Microsoft Corporation. All rights reserved. | |
2 | |
3 using System; | |
4 using System.Diagnostics; | |
5 using System.Diagnostics.CodeAnalysis; | |
6 using System.Globalization; | |
7 using System.IO; | |
8 using System.Runtime.InteropServices; | |
9 using EnvDTE; | |
10 using Microsoft.VisualStudio; | |
11 using Microsoft.VisualStudio.Shell; | |
12 using Microsoft.VisualStudio.Shell.Interop; | |
13 using IServiceProvider = System.IServiceProvider; | |
14 using VSConstants = Microsoft.VisualStudio.VSConstants; | |
15 | |
16 namespace Microsoft.VisualStudio.Project.Automation | |
17 { | |
18 /// <summary> | |
19 /// Represents an automation object for a file in a project | |
20 /// </summary> | |
21 [SuppressMessage("Microsoft.Interoperability", "CA1405:ComVisibleTypeBas
eTypesShouldBeComVisible")] | |
22 [ComVisible(true), CLSCompliant(false)] | |
23 public class OAFileItem : OAProjectItem<FileNode> | |
24 { | |
25 #region ctors | |
26 public OAFileItem(OAProject project, FileNode node) | |
27 : base(project, node) | |
28 { | |
29 } | |
30 | |
31 #endregion | |
32 | |
33 #region overridden methods | |
34 /// <summary> | |
35 /// Returns the dirty state of the document. | |
36 /// </summary> | |
37 /// <exception cref="InvalidOperationException">Is thrown if the
project is closed or it the service provider attached to the project is invalid
.</exception> | |
38 /// <exception cref="ComException">Is thrown if the dirty state
cannot be retrived.</exception> | |
39 public override bool IsDirty | |
40 { | |
41 get | |
42 { | |
43 if(this.Node == null || this.Node.ProjectMgr ==
null || this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null) | |
44 { | |
45 throw new InvalidOperationException(); | |
46 } | |
47 bool isDirty = false; | |
48 | |
49 using(AutomationScope scope = new AutomationScop
e(this.Node.ProjectMgr.Site)) | |
50 { | |
51 DocumentManager manager = this.Node.GetD
ocumentManager(); | |
52 | |
53 if(manager == null) | |
54 { | |
55 throw new InvalidOperationExcept
ion(); | |
56 } | |
57 | |
58 bool isOpen, isOpenedByUs; | |
59 uint docCookie; | |
60 IVsPersistDocData persistDocData; | |
61 manager.GetDocInfo(out isOpen, out isDir
ty, out isOpenedByUs, out docCookie, out persistDocData); | |
62 } | |
63 return isDirty; | |
64 } | |
65 | |
66 } | |
67 | |
68 /// <summary> | |
69 /// Gets the Document associated with the item, if one exists. | |
70 /// </summary> | |
71 public override EnvDTE.Document Document | |
72 { | |
73 get | |
74 { | |
75 if(this.Node == null || this.Node.ProjectMgr ==
null || this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null) | |
76 { | |
77 throw new InvalidOperationException(); | |
78 } | |
79 | |
80 EnvDTE.Document document = null; | |
81 | |
82 using(AutomationScope scope = new AutomationScop
e(this.Node.ProjectMgr.Site)) | |
83 { | |
84 IVsUIHierarchy hier; | |
85 uint itemid; | |
86 | |
87 IVsWindowFrame windowFrame; | |
88 | |
89 VsShellUtilities.IsDocumentOpen(this.Nod
e.ProjectMgr.Site, this.Node.Url, VSConstants.LOGVIEWID_Any, out hier, out itemi
d, out windowFrame); | |
90 | |
91 if(windowFrame != null) | |
92 { | |
93 object var; | |
94 ErrorHandler.ThrowOnFailure(wind
owFrame.GetProperty((int)__VSFPROPID.VSFPROPID_DocCookie, out var)); | |
95 object documentAsObject; | |
96 ErrorHandler.ThrowOnFailure(scop
e.Extensibility.GetDocumentFromDocCookie((int)var, out documentAsObject)); | |
97 if(documentAsObject == null) | |
98 { | |
99 throw new InvalidOperati
onException(); | |
100 } | |
101 else | |
102 { | |
103 document = (Document)doc
umentAsObject; | |
104 } | |
105 } | |
106 | |
107 } | |
108 | |
109 return document; | |
110 } | |
111 } | |
112 | |
113 | |
114 /// <summary> | |
115 /// Opens the file item in the specified view. | |
116 /// </summary> | |
117 /// <param name="ViewKind">Specifies the view kind in which to o
pen the item (file)</param> | |
118 /// <returns>Window object</returns> | |
119 public override EnvDTE.Window Open(string viewKind) | |
120 { | |
121 if(this.Node == null || this.Node.ProjectMgr == null ||
this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null) | |
122 { | |
123 throw new InvalidOperationException(); | |
124 } | |
125 | |
126 IVsWindowFrame windowFrame = null; | |
127 IntPtr docData = IntPtr.Zero; | |
128 | |
129 using(AutomationScope scope = new AutomationScope(this.N
ode.ProjectMgr.Site)) | |
130 { | |
131 try | |
132 { | |
133 // Validate input params | |
134 Guid logicalViewGuid = VSConstants.LOGVI
EWID_Primary; | |
135 try | |
136 { | |
137 if(!(String.IsNullOrEmpty(viewKi
nd))) | |
138 { | |
139 logicalViewGuid = new Gu
id(viewKind); | |
140 } | |
141 } | |
142 catch(FormatException) | |
143 { | |
144 // Not a valid guid | |
145 throw new ArgumentException(SR.G
etString(SR.ParameterMustBeAValidGuid, CultureInfo.CurrentUICulture), "viewKind"
); | |
146 } | |
147 | |
148 uint itemid; | |
149 IVsHierarchy ivsHierarchy; | |
150 uint docCookie; | |
151 IVsRunningDocumentTable rdt = this.Node.
ProjectMgr.Site.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumen
tTable; | |
152 Debug.Assert(rdt != null, " Could not ge
t running document table from the services exposed by this project"); | |
153 if(rdt == null) | |
154 { | |
155 throw new InvalidOperationExcept
ion(); | |
156 } | |
157 | |
158 ErrorHandler.ThrowOnFailure(rdt.FindAndL
ockDocument((uint)_VSRDTFLAGS.RDT_NoLock, this.Node.Url, out ivsHierarchy, out i
temid, out docData, out docCookie)); | |
159 | |
160 // Open the file using the IVsProject3 i
nterface | |
161 ErrorHandler.ThrowOnFailure(this.Node.Pr
ojectMgr.OpenItem(this.Node.ID, ref logicalViewGuid, docData, out windowFrame)); | |
162 | |
163 } | |
164 finally | |
165 { | |
166 if(docData != IntPtr.Zero) | |
167 { | |
168 Marshal.Release(docData); | |
169 } | |
170 } | |
171 } | |
172 | |
173 // Get the automation object and return it | |
174 return ((windowFrame != null) ? VsShellUtilities.GetWind
owObject(windowFrame) : null); | |
175 } | |
176 | |
177 /// <summary> | |
178 /// Saves the project item. | |
179 /// </summary> | |
180 /// <param name="fileName">The name with which to save the proje
ct or project item.</param> | |
181 /// <exception cref="InvalidOperationException">Is thrown if the
save operation failes.</exception> | |
182 /// <exception cref="ArgumentNullException">Is thrown if fileNam
e is null.</exception> | |
183 public override void Save(string fileName) | |
184 { | |
185 this.DoSave(false, fileName); | |
186 } | |
187 | |
188 /// <summary> | |
189 /// Saves the project item. | |
190 /// </summary> | |
191 /// <param name="fileName">The file name with which to save the
solution, project, or project item. If the file exists, it is overwritten</param
> | |
192 /// <returns>true if the rename was successful. False if Save as
failes</returns> | |
193 public override bool SaveAs(string fileName) | |
194 { | |
195 try | |
196 { | |
197 this.DoSave(true, fileName); | |
198 } | |
199 catch(InvalidOperationException) | |
200 { | |
201 return false; | |
202 } | |
203 catch(COMException) | |
204 { | |
205 return false; | |
206 } | |
207 return true; | |
208 } | |
209 | |
210 /// <summary> | |
211 /// Gets a value indicating whether the project item is open in
a particular view type. | |
212 /// </summary> | |
213 /// <param name="viewKind">A Constants.vsViewKind* indicating th
e type of view to check./param> | |
214 /// <returns>A Boolean value indicating true if the project is o
pen in the given view type; false if not. </returns> | |
215 public override bool get_IsOpen(string viewKind) | |
216 { | |
217 if(this.Node == null || this.Node.ProjectMgr == null ||
this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null) | |
218 { | |
219 throw new InvalidOperationException(); | |
220 } | |
221 | |
222 // Validate input params | |
223 Guid logicalViewGuid = VSConstants.LOGVIEWID_Primary; | |
224 try | |
225 { | |
226 if(!(String.IsNullOrEmpty(viewKind))) | |
227 { | |
228 logicalViewGuid = new Guid(viewKind); | |
229 } | |
230 } | |
231 catch(FormatException) | |
232 { | |
233 // Not a valid guid | |
234 throw new ArgumentException(SR.GetString(SR.Para
meterMustBeAValidGuid, CultureInfo.CurrentUICulture), "viewKind"); | |
235 } | |
236 | |
237 bool isOpen = false; | |
238 | |
239 using(AutomationScope scope = new AutomationScope(this.N
ode.ProjectMgr.Site)) | |
240 { | |
241 IVsUIHierarchy hier; | |
242 uint itemid; | |
243 | |
244 IVsWindowFrame windowFrame; | |
245 | |
246 isOpen = VsShellUtilities.IsDocumentOpen(this.No
de.ProjectMgr.Site, this.Node.Url, logicalViewGuid, out hier, out itemid, out wi
ndowFrame); | |
247 | |
248 } | |
249 | |
250 return isOpen; | |
251 } | |
252 | |
253 /// <summary> | |
254 /// Gets the ProjectItems for the object. | |
255 /// </summary> | |
256 public override ProjectItems ProjectItems | |
257 { | |
258 get | |
259 { | |
260 if(this.Project.Project.CanFileNodesHaveChilds) | |
261 return new OAProjectItems(this.Project,
this.Node); | |
262 else | |
263 return base.ProjectItems; | |
264 } | |
265 } | |
266 | |
267 | |
268 #endregion | |
269 | |
270 #region helpers | |
271 /// <summary> | |
272 /// Saves or Save As the file | |
273 /// </summary> | |
274 /// <param name="isCalledFromSaveAs">Flag determining which Save
method called , the SaveAs or the Save.</param> | |
275 /// <param name="fileName">The name of the project file.</param>
| |
276 private void DoSave(bool isCalledFromSaveAs, string fileName) | |
277 { | |
278 if(fileName == null) | |
279 { | |
280 throw new ArgumentNullException("fileName"); | |
281 } | |
282 | |
283 if(this.Node == null || this.Node.ProjectMgr == null ||
this.Node.ProjectMgr.IsClosed || this.Node.ProjectMgr.Site == null) | |
284 { | |
285 throw new InvalidOperationException(); | |
286 } | |
287 | |
288 using(AutomationScope scope = new AutomationScope(this.N
ode.ProjectMgr.Site)) | |
289 { | |
290 IntPtr docData = IntPtr.Zero; | |
291 | |
292 try | |
293 { | |
294 IVsRunningDocumentTable rdt = this.Node.
ProjectMgr.Site.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumen
tTable; | |
295 Debug.Assert(rdt != null, " Could not ge
t running document table from the services exposed by this project"); | |
296 if(rdt == null) | |
297 { | |
298 throw new InvalidOperationExcept
ion(); | |
299 } | |
300 | |
301 // First we see if someone else has open
ed the requested view of the file. | |
302 uint itemid; | |
303 IVsHierarchy ivsHierarchy; | |
304 uint docCookie; | |
305 int canceled; | |
306 string url = this.Node.Url; | |
307 | |
308 ErrorHandler.ThrowOnFailure(rdt.FindAndL
ockDocument((uint)_VSRDTFLAGS.RDT_NoLock, url, out ivsHierarchy, out itemid, out
docData, out docCookie)); | |
309 | |
310 // If an empty file name is passed in fo
r Save then make the file name the project name. | |
311 if(!isCalledFromSaveAs && fileName.Lengt
h == 0) | |
312 { | |
313 ErrorHandler.ThrowOnFailure(this
.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, url, this.Node.ID, docD
ata, out canceled)); | |
314 } | |
315 else | |
316 { | |
317 Utilities.ValidateFileName(this.
Node.ProjectMgr.Site, fileName); | |
318 | |
319 // Compute the fullpath from the
directory of the existing Url. | |
320 string fullPath = fileName; | |
321 if(!Path.IsPathRooted(fileName)) | |
322 { | |
323 string directory = Path.
GetDirectoryName(url); | |
324 fullPath = Path.Combine(
directory, fileName); | |
325 } | |
326 | |
327 if(!isCalledFromSaveAs) | |
328 { | |
329 if(!NativeMethods.IsSame
Path(this.Node.Url, fullPath)) | |
330 { | |
331 throw new Invali
dOperationException(); | |
332 } | |
333 | |
334 ErrorHandler.ThrowOnFail
ure(this.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, fullPath, this.
Node.ID, docData, out canceled)); | |
335 } | |
336 else | |
337 { | |
338 ErrorHandler.ThrowOnFail
ure(this.Node.ProjectMgr.SaveItem(VSSAVEFLAGS.VSSAVE_SilentSave, fullPath, this.
Node.ID, docData, out canceled)); | |
339 } | |
340 } | |
341 | |
342 if(canceled == 1) | |
343 { | |
344 throw new InvalidOperationExcept
ion(); | |
345 } | |
346 } | |
347 catch(COMException e) | |
348 { | |
349 throw new InvalidOperationException(e.Me
ssage); | |
350 } | |
351 finally | |
352 { | |
353 if(docData != IntPtr.Zero) | |
354 { | |
355 Marshal.Release(docData); | |
356 } | |
357 } | |
358 } | |
359 | |
360 } | |
361 #endregion | |
362 | |
363 } | |
364 } | |
OLD | NEW |