123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- using FastReport.Controls;
- using FastReport.Editor.Syntax.Parsers;
- using FastReport.Engine;
- using FastReport.Utils;
- using ICSharpCode.AvalonEdit.CodeCompletion;
- using ICSharpCode.AvalonEdit.Document;
- using ICSharpCode.AvalonEdit.Editing;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Windows.Forms;
- namespace FastReport.Design.PageDesigners.Code
- {
- partial class AvalonSyntaxEditor
- {
- private void DoCodeCompletion(CompletionEventArgs e)
- {
- List<string> parts = e.Text.Split('.').ToList();
- string filter = "";
-
- if (e.Action == CompletionAction.CtrlSpacePressed)
- {
- // last item is incomplete - we will use it as a filter
- if (parts.Count > 0)
- {
- filter = parts[parts.Count - 1];
- parts.RemoveAt(parts.Count - 1);
- }
- }
-
- if (parts.Count == 0)
- {
- // list all report objects
- var list = new List<NamedItem>();
- foreach (Base obj in report.AllObjects)
- {
- if (string.IsNullOrEmpty(obj.Name))
- continue;
- list.Add(new NamedItem(obj.Name, obj.GetType()));
- }
- list.Add(new NamedItem("Report", typeof(Report)));
- list.Add(new NamedItem("Engine", typeof(ReportEngine)));
- list.Sort((x, y) => x.Name.CompareTo(y.Name));
-
- foreach (var obj in list)
- {
- if (obj.Name.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) == -1)
- continue;
- string description = obj.Type.Name + " " + obj.Name;
- System.Drawing.Image image = null;
- var objInfo = RegisteredObjects.FindObject(obj.Type);
- if (objInfo != null)
- image = report.Designer.GetImage(objInfo.ImageIndex);
- e.CompletionData.Add(new CompletionData(obj.Name, description, image));
- }
- }
- else
- {
- Type rootType = null;
- // report object
- object root = report.FindObject(parts[0]);
- if (root != null)
- rootType = root.GetType();
- else
- {
- // some frequently used types like Color?
- if (parts[0] == "Color")
- rootType = typeof(System.Drawing.Color);
- else if (parts[0] == "Report")
- rootType = typeof(Report);
- else if (parts[0] == "Engine")
- rootType = typeof(ReportEngine);
- }
- if (rootType != null)
- {
- for (int i = 1; i < parts.Count; i++)
- {
- PropertyInfo member = null;
- try
- {
- member = rootType.GetProperty(parts[i]);
- }
- catch
- {
- // ambiguous properties found, take first one
- member = rootType.GetProperties().Where(x => x.Name == parts[i]).FirstOrDefault();
- }
- if (member != null)
- rootType = member.PropertyType;
- else
- {
- rootType = null;
- break;
- }
- }
- }
- if (rootType != null)
- {
- if (e.Action == CompletionAction.EqualEntered)
- {
- if (rootType.IsEnum)
- {
- // list enum members
- foreach(var name in Enum.GetNames(rootType))
- {
- var fieldInfo = rootType.GetField(name);
- e.CompletionData.Add(new CompletionData(rootType.Name + "." + name, ReflectionRepository.DescriptionHelper.GetDescription(fieldInfo), null));
- }
- }
- }
- else
- {
- var members = rootType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).ToList();
- members.Sort((x, y) => (x.Name.CompareTo(y.Name)));
- foreach (var member in members)
- {
- if (!string.IsNullOrEmpty(filter) && member.Name.IndexOf(filter, StringComparison.InvariantCultureIgnoreCase) == -1)
- continue;
- string description = "";
- System.Drawing.Image image = null;
- if (member.MemberType == MemberTypes.Property)
- {
- var propInfo = member as PropertyInfo;
- image = report.Designer.GetImage(78);
- description = report.CodeHelper.GetPropertySignature(propInfo, true);
- description += "<br/>" + ReflectionRepository.DescriptionHelper.GetDescription(member);
- }
- else if (member.MemberType == MemberTypes.Method)
- {
- var methodInfo = member as MethodInfo;
- if (methodInfo.IsSpecialName)
- continue;
- image = report.Designer.GetImage(199);
- description = report.CodeHelper.GetMethodSignature(methodInfo, true);
- description += "<br/>" + ReflectionRepository.DescriptionHelper.GetDescription(methodInfo);
- description += "<br/>";
- foreach (ParameterInfo parInfo in methodInfo.GetParameters())
- {
- // special case - skip "thisReport" parameter
- if (parInfo.Name == "thisReport")
- continue;
- string s = ReflectionRepository.DescriptionHelper.GetDescription(parInfo);
- s = s.Replace("<b>", "{i}").Replace("</b>:", "{/i}").Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace("{i}", "<i>").Replace("{/i}", "</i>");
- description += "<br/>" + s + "<br/>";
- }
- description = description.Replace("\t", "<br/>");
- }
- else
- {
- continue;
- }
- if (description.EndsWith("<br/>"))
- description = description.Substring(0, description.Length - 5);
- e.CompletionData.Add(new CompletionData(member.Name, description, image));
- }
- }
- }
- }
- }
- private class NamedItem
- {
- public string Name { get; }
- public Type Type { get; }
- public NamedItem(string name, Type type)
- {
- Name = name;
- Type = type;
- }
- }
- private class CompletionData : ICompletionData
- {
- private string htmlDescription;
- private HtmlDescriptionTextBlock descriptionTextBlock;
- public CompletionData(string text, string htmlDescription, System.Drawing.Image image)
- {
- this.Text = text;
- this.htmlDescription = htmlDescription;
- this.Image = Helper.GetImage(image);
- }
- public System.Windows.Media.ImageSource Image { get; }
- public string Text { get; private set; }
- public object Content => this.Text;
- public object Description
- {
- get
- {
- if (descriptionTextBlock == null)
- CreateTextBlock();
- return descriptionTextBlock;
- }
- set { }
- }
- public double Priority => 0;
- public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
- {
- textArea.Document.Replace(completionSegment, this.Text);
- }
- private void CreateTextBlock()
- {
- descriptionTextBlock = new HtmlDescriptionTextBlock();
- descriptionTextBlock.Image = this.Image;
- descriptionTextBlock.Description = this.htmlDescription;
- descriptionTextBlock.ParseDescription();
- }
- }
- }
- }
|