PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Python/Product/Profiling/Profiling/StandaloneTargetView.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 284 lines | 189 code | 29 blank | 66 comment | 32 complexity | 57442780297284555246c030127a9a67 MD5 | raw file
  1. // Python Tools for Visual Studio
  2. // Copyright(c) Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the License); you may not use
  6. // this file except in compliance with the License. You may obtain a copy of the
  7. // License at http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
  10. // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
  11. // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  12. // MERCHANTABLITY OR NON-INFRINGEMENT.
  13. //
  14. // See the Apache Version 2.0 License for specific language governing
  15. // permissions and limitations under the License.
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Collections.ObjectModel;
  19. using System.ComponentModel;
  20. using System.Diagnostics;
  21. using System.IO;
  22. using System.Linq;
  23. using Microsoft.PythonTools.Interpreter;
  24. using Microsoft.VisualStudio.ComponentModelHost;
  25. namespace Microsoft.PythonTools.Profiling {
  26. /// <summary>
  27. /// Provides a view model for the StandaloneTarget class.
  28. /// </summary>
  29. public sealed class StandaloneTargetView : INotifyPropertyChanged {
  30. private ReadOnlyCollection<PythonInterpreterView> _availableInterpreters;
  31. private readonly PythonInterpreterView _customInterpreter;
  32. private PythonInterpreterView _interpreter;
  33. private string _interpreterPath;
  34. private bool _canSpecifyInterpreterPath;
  35. private string _workingDirectory;
  36. private string _scriptPath;
  37. private string _arguments;
  38. private bool _isValid;
  39. /// <summary>
  40. /// Create a StandaloneTargetView with default values.
  41. /// </summary>
  42. [Obsolete("An IServiceProvider should be provided")]
  43. public StandaloneTargetView()
  44. : this(PythonProfilingPackage.Instance) {
  45. }
  46. public StandaloneTargetView(IServiceProvider serviceProvider) {
  47. var componentService = (IComponentModel)(serviceProvider.GetService(typeof(SComponentModel)));
  48. var interpreterProviders = componentService.DefaultExportProvider.GetExports<IPythonInterpreterFactoryProvider, Dictionary<string, object>>();
  49. var interpreterOptions = componentService.GetService<IInterpreterOptionsService>();
  50. var registry = componentService.GetService<IInterpreterRegistryService>();
  51. var pythonService = componentService.GetService<PythonToolsService>();
  52. var availableInterpreters = registry.Configurations.Select(
  53. config => new PythonInterpreterView(
  54. config.FullDescription,
  55. config.Id,
  56. config.InterpreterPath
  57. )
  58. ).ToList();
  59. _customInterpreter = new PythonInterpreterView("Other...", "", null);
  60. availableInterpreters.Add(_customInterpreter);
  61. _availableInterpreters = new ReadOnlyCollection<PythonInterpreterView>(availableInterpreters);
  62. _interpreterPath = null;
  63. _canSpecifyInterpreterPath = false;
  64. _scriptPath = null;
  65. _workingDirectory = null;
  66. _arguments = null;
  67. _isValid = false;
  68. PropertyChanged += new PropertyChangedEventHandler(StandaloneTargetView_PropertyChanged);
  69. if (IsAnyAvailableInterpreters) {
  70. var defaultId = interpreterOptions.DefaultInterpreterId;
  71. Interpreter = AvailableInterpreters.FirstOrDefault(v => v.Id == defaultId);
  72. }
  73. }
  74. /// <summary>
  75. /// Create a StandaloneTargetView with values taken from a template.
  76. /// </summary>
  77. public StandaloneTargetView(StandaloneTarget template)
  78. : this(PythonProfilingPackage.Instance, template) {
  79. }
  80. public StandaloneTargetView(IServiceProvider serviceProvider, StandaloneTarget template)
  81. : this(serviceProvider) {
  82. if (template.PythonInterpreter != null) {
  83. if (IsAnyAvailableInterpreters) {
  84. Interpreter = AvailableInterpreters
  85. .FirstOrDefault(v => v.Id == template.PythonInterpreter.Id);
  86. } else {
  87. Interpreter = _customInterpreter;
  88. }
  89. } else {
  90. InterpreterPath = template.InterpreterPath;
  91. }
  92. ScriptPath = template.Script;
  93. WorkingDirectory = template.WorkingDirectory;
  94. Arguments = template.Arguments;
  95. }
  96. /// <summary>
  97. /// Returns a StandaloneTarget with values taken from the view model.
  98. /// </summary>
  99. /// <returns></returns>
  100. public StandaloneTarget GetTarget() {
  101. if (IsValid) {
  102. return new StandaloneTarget {
  103. PythonInterpreter = CanSpecifyInterpreterPath ? null : Interpreter.GetInterpreter(),
  104. InterpreterPath = CanSpecifyInterpreterPath ? InterpreterPath : null,
  105. Script = ScriptPath ?? string.Empty,
  106. WorkingDirectory = WorkingDirectory ?? string.Empty,
  107. Arguments = Arguments ?? string.Empty
  108. };
  109. } else {
  110. return null;
  111. }
  112. }
  113. /// <summary>
  114. /// The interpreters that may be selected.
  115. /// </summary>
  116. public ReadOnlyCollection<PythonInterpreterView> AvailableInterpreters {
  117. get {
  118. return _availableInterpreters;
  119. }
  120. }
  121. /// <summary>
  122. /// True if AvailableInterpreters has at least one item.
  123. /// </summary>
  124. public bool IsAnyAvailableInterpreters {
  125. get {
  126. return _availableInterpreters.Count > 0;
  127. }
  128. }
  129. /// <summary>
  130. /// The currently selected Python interpreter. Setting this to null will select a
  131. /// custom interpreter.
  132. /// </summary>
  133. public PythonInterpreterView Interpreter {
  134. get {
  135. return _interpreter;
  136. }
  137. set {
  138. if (_interpreter != value) {
  139. _interpreter = value ?? _customInterpreter;
  140. OnPropertyChanged("Interpreter");
  141. CanSpecifyInterpreterPath = (_interpreter == _customInterpreter);
  142. }
  143. }
  144. }
  145. /// <summary>
  146. /// The current interpreter path. This can be set regardless of the value of
  147. /// CanSpecifyInterpreterPath.
  148. /// </summary>
  149. public string InterpreterPath {
  150. get {
  151. return _interpreterPath;
  152. }
  153. set {
  154. if (_interpreterPath != value) {
  155. _interpreterPath = value;
  156. OnPropertyChanged("InterpreterPath");
  157. }
  158. }
  159. }
  160. /// <summary>
  161. /// True if InterpreterPath is valid; false if it will be ignored.
  162. /// </summary>
  163. public bool CanSpecifyInterpreterPath {
  164. get {
  165. return _canSpecifyInterpreterPath;
  166. }
  167. private set {
  168. if (_canSpecifyInterpreterPath != value) {
  169. _canSpecifyInterpreterPath = value;
  170. OnPropertyChanged("CanSpecifyInterpreterPath");
  171. }
  172. }
  173. }
  174. /// <summary>
  175. /// The current script path.
  176. /// </summary>
  177. public string ScriptPath {
  178. get {
  179. return _scriptPath;
  180. }
  181. set {
  182. if (_scriptPath != value) {
  183. _scriptPath = value;
  184. OnPropertyChanged("ScriptPath");
  185. //if (string.IsNullOrEmpty(WorkingDirectory)) {
  186. // WorkingDirectory = Path.GetDirectoryName(_scriptPath);
  187. //}
  188. }
  189. }
  190. }
  191. /// <summary>
  192. /// The current working directory.
  193. /// </summary>
  194. public string WorkingDirectory {
  195. get {
  196. return _workingDirectory;
  197. }
  198. set {
  199. if (_workingDirectory != value) {
  200. _workingDirectory = value;
  201. OnPropertyChanged("WorkingDirectory");
  202. }
  203. }
  204. }
  205. /// <summary>
  206. /// The current set of arguments to pass to the script.
  207. /// </summary>
  208. public string Arguments {
  209. get {
  210. return _arguments;
  211. }
  212. set {
  213. if (_arguments != value) {
  214. _arguments = value;
  215. OnPropertyChanged("Arguments");
  216. }
  217. }
  218. }
  219. /// <summary>
  220. /// Receives our own property change events to update IsValid.
  221. /// </summary>
  222. void StandaloneTargetView_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  223. Debug.Assert(sender == this);
  224. if (e.PropertyName != "IsValid") {
  225. IsValid = File.Exists(ScriptPath) &&
  226. Directory.Exists(WorkingDirectory) &&
  227. (CanSpecifyInterpreterPath == false || File.Exists(InterpreterPath));
  228. }
  229. }
  230. /// <summary>
  231. /// True if the settings are valid and all paths exist; otherwise, false.
  232. /// </summary>
  233. public bool IsValid {
  234. get {
  235. return _isValid;
  236. }
  237. private set {
  238. if (_isValid != value) {
  239. _isValid = value;
  240. OnPropertyChanged("IsValid");
  241. }
  242. }
  243. }
  244. private void OnPropertyChanged(string propertyName) {
  245. var evt = PropertyChanged;
  246. if (evt != null) {
  247. evt(this, new PropertyChangedEventArgs(propertyName));
  248. }
  249. }
  250. /// <summary>
  251. /// Raised when the value of a property changes.
  252. /// </summary>
  253. public event PropertyChangedEventHandler PropertyChanged;
  254. }
  255. }