using System; using System.Linq; using System.Linq.Expressions; using System.Runtime.InteropServices; namespace InABox.Core { [UserTracking(typeof(User))] public class CustomProperty : Entity, IProperty, IPersistent, IRemotable, ISequenceable, ILicense { public Type? _class; private BaseEditor? _editor; private Func _getter; private string _name = ""; private Action _setter; private string _type; private Type type = typeof(object); private string _caption; private long _sequence; private string _page; public CustomProperty() { Visible = true; Editable = true; Required = false; HasEditor = true; } [MemoEditor(Visible = Core.Visible.Default)] [EditorSequence(5)] public string Comment { get; set; } [CheckBoxEditor(Visible = Core.Visible.Default)] [EditorSequence(8)] public bool Visible { get => Editor.Visible == Core.Visible.Hidden ? false : true; set => Editor.Visible = value ? Core.Visible.Optional : Core.Visible.Hidden; } [CheckBoxEditor(Visible = Core.Visible.Optional)] [EditorSequence(9)] public bool Editable { get => Editor.Editable == Core.Editable.Enabled; set => Editor.Editable = value ? Core.Editable.Enabled : Core.Editable.Hidden; } [ComboLookupEditor(typeof(PropertyClassLookups))] [EditorSequence(1)] public string Class { get => _class != null ? _class.EntityName() : ""; set { CoreUtils.TryGetEntity(value, out _class); CheckExpressions(); } } [EditorSequence(2)] public string Name { get => _name; set { _name = value; CheckExpressions(); } } [ComboLookupEditor(typeof(PropertyTypeLookups), Visible = Core.Visible.Default)] [EditorSequence(3)] public string Type { get => _type; set { _type = value; try { type = CoreUtils.GetEntityOrNull(_type) ?? typeof(object); } catch { type = typeof(object); } _editor = EditorUtils.GetEditor(type); IsEntityLink = type.GetInterfaces().Contains(typeof(IEntityLink)); } } [DoNotPersist] [DoNotSerialize] public Type PropertyType { get => type; set { type = value; _type = value.EntityName(); _editor = EditorUtils.GetEditor(type); IsEntityLink = type.GetInterfaces().Contains(typeof(IEntityLink)); } } [NullEditor] public BaseEditor Editor { get { if (_editor == null) { _editor = EditorUtils.GetEditor(PropertyType); if (_editor == null) _editor = new NullEditor(); _editor.Caption = Caption; _editor.EditorSequence = (int)Sequence; _editor.Page = Page; //_editor.Editable = Editable ? Core.Editable.Enabled : Core.Editable.Disabled; //_editor.Visible = Visible ? Core.Visible.Optional : Core.Visible.Disabled; } return _editor; } set => _editor = value; } [NullEditor] public bool HasEditor { get; set; } [TextBoxEditor(Visible = Core.Visible.Optional)] [EditorSequence(6)] public string Caption { get => _caption; set { _caption = value; if (_editor != null) { _editor.Caption = _caption; } } } [TextBoxEditor(Visible = Core.Visible.Optional)] [EditorSequence(7)] public string Page { get => _page; set { _page = value; if(_editor != null) { _editor.Page = _page; } } } [CheckBoxEditor(Visible = Core.Visible.Optional)] [EditorSequence(8)] public bool Required { get; set; } [NullEditor] [EditorSequence(9)] public LoggablePropertyAttribute? Loggable { get; set; } [NullEditor] public long Sequence { get => _sequence; set { _sequence = value; if (_editor != null) { _editor.EditorSequence = (int)_sequence; } } } public IProperty? Parent { get; set; } public bool IsEntityLink { get; set; } public Expression Expression() { if (_class is null) throw new Exception("No class for CustomProperty"); return CoreUtils.CreateIndexExpression(_class, "UserProperties", Name); } public Func Getter() { return _getter; } public Action Setter() { return _setter; } public override string ToString() { return string.Format("{0}.{1}", Class, Name); } private void CheckExpressions() { if (_class == null) return; if (string.IsNullOrEmpty(Name)) return; try { _getter = Expressions.Getter(_class, "UserProperties", Name); _setter = Expressions.Setter(_class, "UserProperties", Name); } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } } } public class CustomPropertyLookups : EntityLookup { public override Columns DefineColumns() { return base.DefineColumns() .Add(x => x.Class) .Add(x => x.Name); } //public string FormatLookup(Dictionary values, IEnumerable exclude) //{ // return LookupFactory.DefaultFormatLookup(values, exclude.Concat(new String[] { "ID" })); //} public override Filter? DefineFilter() { return null; } public override SortOrder DefineSortOrder() { return new SortOrder(x => x.Class).ThenBy(x => x.Sequence); } } }