private void Edit()
        {
            if (selectedNodes.Count <= 0)
            {
                return;
            }

            if (selectedNodes.Count == 1)
            {
                EditNode(selectedNodes[0]);
                return;
            }

            PickWindow w = new PickWindow(selectedNodes.Select(x => x.Instance.GetProperty("mRID") + " : " + x.Instance.Class.Name).ToList());

            w.ShowDialog();

            int i = w.Result;

            if (i < 0)
            {
                return;
            }

            EditNode(selectedNodes[i]);
        }
        private void Functions()
        {
            PickWindow pw = new PickWindow(functions.Select(x => x.Item1));

            pw.ShowDialog();

            if (pw.Result < 0 || pw.Result >= functions.Count)
            {
                return;
            }

            functions[pw.Result].Item2();
            Redraw();
        }
        private void Add()
        {
            PickWindow pw = new PickWindow(profile.ConcreteClasses.Select(x => x.Name).ToList());

            pw.ShowDialog();

            if (pw.Result < 0)
            {
                return;
            }

            Class        type   = profile.ConcreteClasses[pw.Result];
            List <Input> inputs = new List <Input>();
            Vector       center = GetCenter();

            foreach (KeyValuePair <string, Attribute> kvp in type.AllAttributes)
            {
                Input input = new Input()
                {
                    Name = kvp.Key
                };

                switch (kvp.Key)
                {
                case "mRID":
                case "name":
                    input.Value = type.Name + "_" + typeCounts[type];
                    break;

                default:
                    input.Value = "";
                    break;
                }

                switch (kvp.Value.Type)
                {
                case AttributeType.Bool:
                    input.OfferedValues = new List <string>()
                    {
                        "false", "true"
                    };
                    break;

                case AttributeType.Enum:
                    input.OfferedValues = kvp.Value.TargetType.AllAttributes.Keys.ToList();
                    break;

                case AttributeType.Reference:
                    input.OfferedValues = GetNearestTargets(center.X, center.Y, kvp.Value.TargetType);
                    break;
                }

                inputs.Add(input);
            }

            EditWindow w = new EditWindow(inputs)
            {
                Title = "Add " + type.Name
            };

            w.ShowDialog();
            Dictionary <string, string> fields = w.Result;

            if (fields == null)
            {
                return;
            }

            Instance instance = new Instance(type);

            foreach (KeyValuePair <string, string> kvp in fields)
            {
                instance.SetProperty(kvp.Key, kvp.Value);
            }

            NodeModel model;

            if (!classToModel.TryGetValue(type.Name, out model))
            {
                return;
            }

            string mrid = instance.GetProperty("mRID");

            if (string.IsNullOrWhiteSpace(mrid))
            {
                return;
            }

            if (nodes.ContainsKey(mrid))
            {
                return;
            }

            Node node = new Node(center.X, center.Y, 0, 1, model, instance);

            nodes.Add(mrid, node);
            ++typeCounts[type];

            foreach (string target in node.OutReferences)
            {
                Node targetNode;

                if (!nodes.TryGetValue(target, out targetNode))
                {
                    continue;
                }

                targetNode.AddInReference(mrid);
            }

            foreach (Node n in selectedNodes)
            {
                n.Selected = false;
            }

            selectedNodes.Clear();

            node.Selected = true;
            selectedNodes.Add(node);

            Redraw();
        }