PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/src/lextm/wiseeditor/feature/ComponentNamerFeature.cs

http://lextudio.googlecode.com/
C# | 412 lines | 304 code | 61 blank | 47 comment | 73 complexity | 9f3b5a88ad5835252c94994bfbb1c1ae MD5 | raw file
Possible License(s): CPL-1.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. using System;
  2. using System.ComponentModel;
  3. using System.ComponentModel.Design;
  4. using System.ComponentModel.Design.Serialization;
  5. using System.Text;
  6. using System.Windows.Forms;
  7. using BeWise.Common.Utils;
  8. using BeWise.SharpBuilderTools.Helpers;
  9. using Borland.Studio.ToolsAPI;
  10. using Lextm.OpenTools;
  11. using Lextm.Diagnostics;
  12. using Lextm.Xml;
  13. using System.Collections.Generic;
  14. using System.Collections;
  15. namespace Lextm.WiseEditor.Feature {
  16. /// <summary>
  17. /// Rename Components feature.
  18. /// </summary>
  19. public class ComponentNamerFeature : CustomFeature {
  20. private const string Name = "Component Namer";
  21. ///<summary>
  22. ///Registers tabs.
  23. ///</summary>
  24. ///<remarks>
  25. /// Used to configure tabs on FormPreferences.
  26. ///</remarks>
  27. protected override void IdeRegisterTabs() {
  28. base.IdeRegisterTabs();
  29. RegisterTab(CreateTabNode(Name, typeof(Gui.ComponentNamerPage)));
  30. }
  31. /**************************************************************/
  32. /* Constructor
  33. /**************************************************************/
  34. public ComponentNamerFeature() {
  35. // binds custom handler to IDE.
  36. IOTAService _Service = OtaUtils.GetService();
  37. _Service.FileNotification += new FileNotificationHandler(OpenCloseFileNotificationHandler);
  38. //RegisterOptionsType(typeof(Preferences));
  39. //StartFileNotification();
  40. }
  41. /**************************************************************/
  42. /* Private
  43. /**************************************************************/
  44. //private static FileNotificationHandler fMenuShortCutNotification;
  45. private static string GetControlPrefix(Type aType) {
  46. string _TypeName = aType.Name;
  47. foreach (ControlPrefix _ControlPrefix in options.ControlPrefixes) {
  48. if (_ControlPrefix.ControlTypeName == _TypeName) {
  49. return _ControlPrefix.Prefix;
  50. }
  51. }
  52. return null;
  53. }
  54. private static string GetCandidateName(Type type) {
  55. string typeName = type.Name;
  56. StringBuilder prefix = new StringBuilder();
  57. // removes a, e, i, o, u, y from the string.
  58. foreach (char charIn in typeName) {
  59. char lower = Char.ToUpperInvariant(charIn);
  60. if ((lower == 'A') || (lower == 'E') || (lower == 'I')
  61. || (lower == 'O') || (lower == 'U') || (lower == 'Y')) {
  62. continue;
  63. } else {
  64. prefix.Append(lower);
  65. }
  66. }
  67. if (Array.IndexOf(options.ControlPrefixes, prefix.ToString()) > -1) {
  68. return null;
  69. } else {
  70. return prefix.ToString();
  71. }
  72. }
  73. private static void SetValidControlName(Control aControl, INameCreationService aNameCreationService, string aName)
  74. {
  75. LoggingService.EnterMethod();
  76. System.Diagnostics.Trace.Assert(aNameCreationService != null);
  77. string _Name = aName;
  78. PropertyDescriptor _PropertyDescriptor = TypeDescriptor.GetProperties(aControl)["Name"];
  79. System.Diagnostics.Trace.Assert(_PropertyDescriptor != null);
  80. if (aNameCreationService.IsValidName(_Name))
  81. {
  82. try
  83. {
  84. _PropertyDescriptor.SetValue(aControl, _Name);
  85. LoggingService.Info("The name is " + _Name + " finally.");
  86. string after = _PropertyDescriptor.GetValue(aControl) as string;
  87. int j = 0;
  88. while (after != _Name)
  89. {
  90. LoggingService.Info("Naming fails, try again.");
  91. _PropertyDescriptor.SetValue(aControl, _Name);
  92. after = _PropertyDescriptor.GetValue(aControl) as string;
  93. j++;
  94. if (j > 10)
  95. {
  96. break;
  97. }
  98. }
  99. LoggingService.LeaveMethod();
  100. return;
  101. }
  102. catch (Exception ex)
  103. {
  104. LoggingService.Error(ex);
  105. }
  106. }
  107. else
  108. {
  109. LoggingService.Warn("Name (" + _Name + ") is not valid.");
  110. }
  111. if (_Name.EndsWith("1", StringComparison.Ordinal))
  112. {
  113. _Name = _Name.TrimEnd(new char[] { '1' });
  114. LoggingService.Info("1 is removed from name.");
  115. }
  116. else
  117. {
  118. LoggingService.Warn("There is not 1 in the name.");
  119. }
  120. int i = 1;
  121. while (true)
  122. {
  123. try
  124. {
  125. _PropertyDescriptor.SetValue(aControl, _Name + i);
  126. LoggingService.Info("The name is " + _Name + i + " finally.");
  127. string after = _PropertyDescriptor.GetValue(aControl) as string;
  128. int j = 0;
  129. while (after != _Name + i)
  130. {
  131. LoggingService.Info("Naming fails, try again.");
  132. _PropertyDescriptor.SetValue(aControl, _Name + i);
  133. after = _PropertyDescriptor.GetValue(aControl) as string;
  134. j++;
  135. if (j > 10)
  136. {
  137. break;
  138. }
  139. }
  140. LoggingService.LeaveMethod();
  141. return;
  142. }
  143. catch (Exception ex)
  144. {
  145. LoggingService.Error(ex);
  146. }
  147. i++;
  148. // To be sure that we don't have an infinit loop for an
  149. // invalid name (Prefix)
  150. if (i > 100)
  151. {
  152. LoggingService.Debug("i > 100, exit.");
  153. LoggingService.LeaveMethod();
  154. return;
  155. }
  156. }
  157. }
  158. private void OpenCloseFileNotificationHandler(object aSender, FileNotificationEventArgs aArgs) {
  159. LoggingService.Debug("enter handler");
  160. try {
  161. if (OtaUtils.IsCSFile(aArgs.FileName) &&
  162. aArgs.NotifyCode == OTAFileNotification.ofnFileOpened) {
  163. IOTAModule _Module = OtaUtils.GetModuleServices().FindModule(aArgs.FileName);
  164. if (_Module != null) {
  165. IDesignerHost _Designer = OtaUtils.GetDesignerForModule(_Module);
  166. if (_Designer != null) {
  167. // this module has a designer, so it is Control, UserControl, or Form.
  168. IComponentChangeService _ChangeService = (IComponentChangeService) _Designer.GetService(typeof(IComponentChangeService));
  169. // drops default handler and installs custom handler.
  170. _ChangeService.ComponentAdded -= new ComponentEventHandler(OnComponentAdded);
  171. _ChangeService.ComponentAdded += new ComponentEventHandler(OnComponentAdded);
  172. LoggingService.Info("component added");
  173. } else {
  174. LoggingService.Warn("component not added");
  175. }
  176. }
  177. } else if (OtaUtils.IsCSFile(aArgs.FileName) && aArgs.NotifyCode == OTAFileNotification.ofnFileClosing) {
  178. IOTAModule _Module = OtaUtils.GetModuleServices().FindModule(aArgs.FileName);
  179. if (_Module != null) {
  180. // Remove the Auto Rename Control Handler
  181. IDesignerHost _Designer = OtaUtils.GetDesignerForModule(_Module);
  182. if (_Designer != null) {
  183. IComponentChangeService _ChangeService = (IComponentChangeService) _Designer.GetService(typeof(IComponentChangeService));
  184. _ChangeService.ComponentAdded -= new ComponentEventHandler(OnComponentAdded);
  185. LoggingService.Info("component removed");
  186. }
  187. }
  188. }
  189. } catch (Exception ex) {
  190. Lextm.Windows.Forms.MessageBoxFactory.Fatal(Name, ex);
  191. }
  192. }
  193. private static IDesignerHost fDesignerHost;
  194. private static IList<Control> fCreatedControls = new List<Control>();
  195. private static Timer fTimerComponentAdded = new Timer();
  196. private void OnRenameComponent(object o, EventArgs e) {
  197. LoggingService.EnterMethod();
  198. fTimerComponentAdded.Enabled = false;
  199. if (fDesignerHost == null) {
  200. LoggingService.Warn("null desinger cache.");
  201. LoggingService.LeaveMethod();
  202. return;
  203. }
  204. foreach(Control _Control in fCreatedControls) {
  205. string _Prefix = GetControlPrefix(_Control.GetType());
  206. if (String.IsNullOrEmpty(_Prefix)) {
  207. LoggingService.Info("This is not a prefix in list.");
  208. _Prefix = GetNewPrefix(_Control.GetType());
  209. if (!String.IsNullOrEmpty(_Prefix)) {
  210. // if not in the list, add this prefix to preferences.
  211. LoggingService.Info("New prefix is adding, " + _Prefix);
  212. AddNewPrefix(_Prefix, _Control.GetType().Name);
  213. } else {
  214. // do not touch this control.
  215. LoggingService.Warn("This type is not added. Ignore this control and break.");
  216. break;
  217. }
  218. }
  219. // names the component.
  220. NameComponent(_Control, _Prefix);
  221. }
  222. fCreatedControls.Clear();
  223. fDesignerHost = null;
  224. LoggingService.LeaveMethod();
  225. }
  226. // whenever a component is added.
  227. private void OnComponentAdded(object sender, ComponentEventArgs ce) {
  228. if (!(bool)PropertyRegistry.Get("EnableAutoRenameControls", false)) {
  229. return;
  230. }
  231. Control _Control = ce.Component as Control;
  232. if (_Control != null) {
  233. IDesignerHost _Designer = OtaUtils.GetDesignerForModule(OtaUtils.GetCurrentModule());
  234. if (_Designer != null && (fDesignerHost == null || _Designer == fDesignerHost) && !_Designer.Loading) {
  235. fDesignerHost = _Designer;
  236. fCreatedControls.Add(_Control);
  237. fTimerComponentAdded.Interval = 500;
  238. fTimerComponentAdded.Tick -= new EventHandler(OnRenameComponent);
  239. fTimerComponentAdded.Tick += new EventHandler(OnRenameComponent);
  240. fTimerComponentAdded.Enabled = true;
  241. }
  242. }
  243. }
  244. #region Preferences
  245. /**************************************************************/
  246. /* Public
  247. /**************************************************************/
  248. private static Preferences options;
  249. public static Preferences GetOptions() {
  250. return options;
  251. }
  252. public override void LoadPreferences() {
  253. base.LoadPreferences();
  254. options = (Preferences)SerializationService.Load(
  255. Lextm.OpenTools.IO.Path.GetPreferencesFile(this.GetType()),
  256. typeof(Preferences));
  257. }
  258. public override void SavePreferences() {
  259. base.SavePreferences();
  260. SerializationService.Save(
  261. Lextm.OpenTools.IO.Path.GetPreferencesFile(this.GetType()),
  262. options);
  263. }
  264. /// <summary>
  265. /// Sets default preferences.
  266. /// </summary>
  267. public override void SetDefaultPreferences() {
  268. base.SetDefaultPreferences();
  269. if (options == null)
  270. {
  271. options = new Preferences();
  272. options.ControlPrefixes = new ControlPrefix[0];
  273. }
  274. if (options.ControlPrefixes == null
  275. || options.ControlPrefixes.Length == 0) {
  276. ArrayList _List = new ArrayList();
  277. _List.Add(new ControlPrefix("bt", "Button"));
  278. _List.Add(new ControlPrefix("chk", "CheckBox"));
  279. _List.Add(new ControlPrefix("cb", "ComboBox"));
  280. _List.Add(new ControlPrefix("lv", "Vista_Api.ListView"));
  281. _List.Add(new ControlPrefix("txt", "TextBox"));
  282. options.ControlPrefixes = (ControlPrefix[]) _List.ToArray(typeof(ControlPrefix));
  283. }
  284. }
  285. ///<summary>
  286. ///All configuration.
  287. ///</summary>
  288. /// <remarks>
  289. /// It should be a Serializable class with public constructor so as to be serialized and deserialized.
  290. /// </remarks>
  291. [System.Serializable]
  292. public sealed class Preferences {
  293. private ControlPrefix[] controlPrefixes;
  294. public ControlPrefix[] ControlPrefixes {
  295. get {
  296. return controlPrefixes;
  297. }
  298. set {
  299. controlPrefixes = value;
  300. }
  301. }
  302. }
  303. #endregion
  304. private static string GetNewPrefix( Type type ) {
  305. Gui.FormNewPrefix form = new Gui.FormNewPrefix();
  306. form.lblControlName.Text = type.Name;
  307. form.txtPrefix.Text = GetCandidateName(type);
  308. if (form.ShowDialog() == DialogResult.OK) {
  309. // gets a new prefix
  310. return form.txtPrefix.Text;
  311. } else {
  312. return null;
  313. }
  314. }
  315. private static string GetComponentName( string _Prefix, Control _Control ) {
  316. Gui.FormComponentName formName = new Gui.FormComponentName();
  317. formName.txtName.Text = _Prefix + _Control.Name;
  318. formName.ShowDialog();
  319. return formName.txtName.Text;
  320. }
  321. private static void NameComponent( Control _Control, string _Prefix ) {
  322. LoggingService.EnterMethod();
  323. if (!_Control.Name.StartsWith(_Prefix, StringComparison.Ordinal)) {
  324. //DesignerTransaction _DesignerTransaction = fDesignerHost.CreateTransaction("RenameComponents");
  325. //using (_DesignerTransaction) {
  326. INameCreationService service = (INameCreationService) fDesignerHost.GetService(typeof(INameCreationService));
  327. SetValidControlName(_Control, service, (GetComponentName(_Prefix, _Control)));
  328. // Complete the designer transaction.
  329. //_DesignerTransaction.Commit();
  330. //}
  331. } else {
  332. LoggingService.Warn("Control " + _Control.Name + " has the prefix already.");
  333. }
  334. LoggingService.LeaveMethod();
  335. }
  336. private void AddNewPrefix( string prefix, string typeName ) {
  337. if (Array.IndexOf(options.ControlPrefixes, prefix) == -1) {
  338. ArrayList list = new ArrayList();
  339. foreach (ControlPrefix controlPrefix in options.ControlPrefixes) {
  340. list.Add(controlPrefix);
  341. }
  342. list.Add(new ControlPrefix(prefix, typeName));
  343. options.ControlPrefixes = null; // releases the resources.
  344. options.ControlPrefixes = (ControlPrefix[]) list.ToArray(typeof(ControlPrefix));
  345. this.SavePreferences();
  346. } else {
  347. LoggingService.Warn("The prefix is already there.");
  348. }
  349. }
  350. }
  351. }