PageRenderTime 35ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/Python/Product/XamlDesignerSupport/WpfEventBindingProvider.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 229 lines | 172 code | 35 blank | 22 comment | 44 complexity | fa68a41ae0b78caac7ce379f0acc844f 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.Linq;
  19. using System.Text;
  20. using Microsoft.PythonTools.Infrastructure;
  21. using Microsoft.PythonTools.Intellisense;
  22. using Microsoft.VisualStudio.Text;
  23. using Microsoft.VisualStudio.Text.Editor;
  24. using Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods;
  25. using Microsoft.Windows.Design.Host;
  26. namespace Microsoft.PythonTools.XamlDesignerSupport {
  27. class WpfEventBindingProvider : EventBindingProvider {
  28. private readonly IXamlDesignerCallback _callback;
  29. public WpfEventBindingProvider(IXamlDesignerCallback callback) {
  30. _callback = callback;
  31. }
  32. public override bool AddEventHandler(EventDescription eventDescription, string objectName, string methodName) {
  33. // we return false here which causes the event handler to always be wired up via XAML instead of via code.
  34. return false;
  35. }
  36. public override bool AllowClassNameForMethodName() {
  37. return true;
  38. }
  39. public override void AppendStatements(EventDescription eventDescription, string methodName, string statements, int relativePosition) {
  40. throw new NotImplementedException();
  41. }
  42. public override string CodeProviderLanguage {
  43. get { return "Python"; }
  44. }
  45. public override bool CreateMethod(EventDescription eventDescription, string methodName, string initialStatements) {
  46. // build the new method handler
  47. var insertPoint = _callback.GetInsertionPoint(null);
  48. if (insertPoint != null) {
  49. var view = _callback.TextView;
  50. var textBuffer = _callback.Buffer;
  51. using (var edit = textBuffer.CreateEdit()) {
  52. var text = BuildMethod(
  53. eventDescription,
  54. methodName,
  55. new string(' ', insertPoint.Indentation),
  56. view.Options.IsConvertTabsToSpacesEnabled() ?
  57. view.Options.GetIndentSize() :
  58. -1);
  59. edit.Insert(insertPoint.Location, text);
  60. edit.Apply();
  61. return true;
  62. }
  63. }
  64. return false;
  65. }
  66. private static string BuildMethod(EventDescription eventDescription, string methodName, string indentation, int tabSize) {
  67. StringBuilder text = new StringBuilder();
  68. text.AppendLine(indentation);
  69. text.Append(indentation);
  70. text.Append("def ");
  71. text.Append(methodName);
  72. text.Append('(');
  73. text.Append("self");
  74. foreach (var param in eventDescription.Parameters) {
  75. text.Append(", ");
  76. text.Append(param.Name);
  77. }
  78. text.AppendLine("):");
  79. if (tabSize < 0) {
  80. text.Append(indentation);
  81. text.Append("\tpass");
  82. } else {
  83. text.Append(indentation);
  84. text.Append(' ', tabSize);
  85. text.Append("pass");
  86. }
  87. text.AppendLine();
  88. return text.ToString();
  89. }
  90. public override string CreateUniqueMethodName(string objectName, EventDescription eventDescription) {
  91. var name = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}", objectName, eventDescription.Name);
  92. int count = 0;
  93. var methods = _callback.FindMethods(
  94. null,
  95. null
  96. );
  97. while (methods.Contains(name)) {
  98. name = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}{2}", objectName, eventDescription.Name, ++count);
  99. }
  100. return name;
  101. }
  102. public override IEnumerable<string> GetCompatibleMethods(EventDescription eventDescription) {
  103. return _callback.FindMethods(null, eventDescription.Parameters.Count() + 1);
  104. }
  105. public override IEnumerable<string> GetMethodHandlers(EventDescription eventDescription, string objectName) {
  106. return new string[0];
  107. }
  108. public override bool IsExistingMethodName(EventDescription eventDescription, string methodName) {
  109. return _callback.FindMethods(null, null).Contains(methodName);
  110. }
  111. private MethodInformation FindMethod(string methodName) {
  112. return _callback.GetMethodInfo(null, methodName);
  113. }
  114. public override bool RemoveEventHandler(EventDescription eventDescription, string objectName, string methodName) {
  115. var method = FindMethod(methodName);
  116. if (method != null && method.IsFound) {
  117. var view = _callback.TextView;
  118. var textBuffer = _callback.Buffer;
  119. // appending a method adds 2 extra newlines, we want to remove those if those are still
  120. // present so that adding a handler and then removing it leaves the buffer unchanged.
  121. using (var edit = textBuffer.CreateEdit()) {
  122. int start = method.Start - 1;
  123. // eat the newline we insert before the method
  124. while (start >= 0) {
  125. var curChar = edit.Snapshot[start];
  126. if (!Char.IsWhiteSpace(curChar)) {
  127. break;
  128. } else if (curChar == ' ' || curChar == '\t') {
  129. start--;
  130. continue;
  131. } else if (curChar == '\n') {
  132. if (start != 0) {
  133. if (edit.Snapshot[start - 1] == '\r') {
  134. start--;
  135. }
  136. }
  137. start--;
  138. break;
  139. } else if (curChar == '\r') {
  140. start--;
  141. break;
  142. }
  143. start--;
  144. }
  145. // eat the newline we insert at the end of the method
  146. int end = method.End;
  147. while (end < edit.Snapshot.Length) {
  148. if (edit.Snapshot[end] == '\n') {
  149. end++;
  150. break;
  151. } else if (edit.Snapshot[end] == '\r') {
  152. if (end < edit.Snapshot.Length - 1 && edit.Snapshot[end + 1] == '\n') {
  153. end += 2;
  154. } else {
  155. end++;
  156. }
  157. break;
  158. } else if (edit.Snapshot[end] == ' ' || edit.Snapshot[end] == '\t') {
  159. end++;
  160. continue;
  161. } else {
  162. break;
  163. }
  164. }
  165. // delete the method and the extra whitespace that we just calculated.
  166. edit.Delete(Span.FromBounds(start + 1, end));
  167. edit.Apply();
  168. }
  169. return true;
  170. }
  171. return false;
  172. }
  173. public override bool RemoveHandlesForName(string elementName) {
  174. throw new NotImplementedException();
  175. }
  176. public override bool RemoveMethod(EventDescription eventDescription, string methodName) {
  177. throw new NotImplementedException();
  178. }
  179. public override void SetClassName(string className) {
  180. }
  181. public override bool ShowMethod(EventDescription eventDescription, string methodName) {
  182. var method = FindMethod(methodName);
  183. if (method != null && method.IsFound) {
  184. var view = _callback.TextView;
  185. view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, method.Start));
  186. view.Caret.EnsureVisible();
  187. return true;
  188. }
  189. return false;
  190. }
  191. public override void ValidateMethodName(EventDescription eventDescription, string methodName) {
  192. }
  193. }
  194. }