Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/15/11 23:02:01 (13 years ago)
Author:
mkommend
Message:

#1479: Merged trunk changes, refactored grammar editor and added copy functionality.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.cs

    r6409 r6415  
    2525using System.Linq;
    2626using System.Windows.Forms;
    27 using HeuristicLab.Collections;
    2827using HeuristicLab.Common;
    2928using HeuristicLab.Core.Views;
     
    3534  [Content(typeof(ISymbolicExpressionGrammar), false)]
    3635  public partial class SymbolicExpressionGrammarEditorView : NamedItemView {
    37     private ObservableList<ISymbolicExpressionTreeNode> selectedSymbolicExpressionTreeNodes;
    38 
    3936    public SymbolicExpressionGrammarEditorView() {
    4037      InitializeComponent();
    41       selectedSymbolicExpressionTreeNodes = new ObservableList<ISymbolicExpressionTreeNode>();
    4238    }
    4339
     
    5652      get { return (ISymbolicExpressionGrammar)base.Content; }
    5753      set { base.Content = value; }
     54    }
     55
     56    protected override void SetEnabledStateOfControls() {
     57      base.SetEnabledStateOfControls();
     58      addButton.Enabled = Content != null;
     59      removeButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
     60      copyButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
     61    }
     62
     63    protected override void OnContentChanged() {
     64      base.OnContentChanged();
     65      if (Content != null) {
     66        symbolsTreeView.Nodes.Clear();
     67        UpdateSymbolsTreeView();
     68        symbolsTreeView.ExpandAll();
     69        allowedChildSymbolsControl.Grammar = Content;
     70        allowedChildSymbolsControl.Symbol = null;
     71        symbolDetailsViewHost.Content = null;
     72      } else {
     73        symbolsTreeView.Nodes.Clear();
     74        allowedChildSymbolsControl.Grammar = null;
     75        symbolDetailsViewHost.Content = null;
     76      }
    5877    }
    5978
     
    7998        symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
    8099
    81       RebuildSymbolsTreeView();
     100      allowedChildSymbolsControl.Grammar = Content;
     101
     102      UpdateSymbolsTreeView();
    82103      if (symbol != null && Content.ContainsSymbol(symbol)) {
    83         BuildAllowedChildSymbolsTree(symbol);
     104        allowedChildSymbolsControl.Symbol = symbol;
    84105        symbolDetailsViewHost.Content = symbol;
    85106        symbolsTreeView.SelectedNode = IterateSymbolTreeNodes().Where(n => n.Tag == symbol).ToList().FirstOrDefault();
     
    88109    #endregion
    89110
    90     protected override void SetEnabledStateOfControls() {
    91       base.SetEnabledStateOfControls();
    92     }
    93 
    94     protected override void OnContentChanged() {
    95       base.OnContentChanged();
    96       if (Content != null) {
    97         RebuildSymbolsTreeView();
    98         allowedChildSymbolsControl.Tree = null;
    99         symbolDetailsViewHost.Content = null;
    100       } else {
    101         symbolsTreeView.Nodes.Clear();
    102         allowedChildSymbolsControl.Tree = null;
    103         symbolDetailsViewHost.Content = null;
    104       }
     111    private void UpdateSymbolsTreeView() {
     112      var symbols = Content.Symbols.ToList();
     113      foreach (var treeNode in IterateSymbolTreeNodes().ToList()) {
     114        var symbol = treeNode.Tag as ISymbol;
     115        if (!symbols.Contains(symbol))
     116          treeNode.Remove();
     117      }
     118
     119      var groupSymbols = symbols.OfType<GroupSymbol>().ToList();
     120      var topLevelSymbols = Content.Symbols.Where(s => !groupSymbols.Any(g => g.Symbols.Contains(s)));
     121      AddChildTreeNodes(symbolsTreeView.Nodes, topLevelSymbols);
     122
     123      RebuildImageList();
    105124    }
    106125
    107126    private void AddChildTreeNodes(TreeNodeCollection collection, IEnumerable<ISymbol> symbols) {
    108127      foreach (ISymbol symbol in symbols) {
    109         var node = new TreeNode();
    110         node.Name = symbol.Name;
    111         node.Text = symbol.Name;
    112         node.Tag = symbol;
    113         node.Checked = symbol.Enabled;
    114         collection.Add(node);
     128        TreeNode node = collection.Cast<TreeNode>().Where(n => n.Tag == symbol).FirstOrDefault();
     129        if (node == null) {
     130          node = new TreeNode();
     131          node.Name = symbol.Name;
     132          node.Text = symbol.Name;
     133          node.Tag = symbol;
     134          node.Checked = symbol.Enabled;
     135          collection.Add(node);
     136        }
    115137        var groupSymbol = symbol as GroupSymbol;
    116138        if (groupSymbol != null) AddChildTreeNodes(node.Nodes, groupSymbol.Symbols);
     
    122144        var symbol = (ISymbol)e.Node.Tag;
    123145        symbolDetailsViewHost.Content = symbol;
    124         selectedSymbolicExpressionTreeNodes.Clear();
    125         BuildAllowedChildSymbolsTree(symbol);
     146        allowedChildSymbolsControl.Symbol = symbol;
    126147      }
    127148      removeButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
     149      copyButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
    128150    }
    129151
    130152    private void symbolsTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
    131153      if (e.Action != TreeViewAction.Unknown) {
    132         DeregisterContentEvents();
     154        Content.StartGrammarManipulation();
     155        allowedChildSymbolsControl.Symbol = null;
    133156        var symbol = (ISymbol)e.Node.Tag;
    134157        symbol.Enabled = e.Node.Checked;
     
    138161        if (symbolsTreeView.SelectedNode != null) {
    139162          symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
    140           selectedSymbolicExpressionTreeNodes.Clear();
    141           BuildAllowedChildSymbolsTree(symbol);
    142         }
    143         RegisterContentEvents();
    144       }
    145     }
    146 
    147     private void RebuildSymbolsTreeView() {
    148       symbolsTreeView.Nodes.Clear();
    149       var symbols = Content.Symbols.ToList();
    150       var groupSymbols = symbols.OfType<GroupSymbol>().ToList();
    151       var topLevelSymbols = Content.Symbols.Where(s => !groupSymbols.Any(g => g.Symbols.Contains(s)));
    152       AddChildTreeNodes(symbolsTreeView.Nodes, topLevelSymbols);
    153 
    154       RebuildImageList();
    155       symbolsTreeView.ExpandAll();
    156     }
    157 
    158     private void BuildAllowedChildSymbolsTree(ISymbol symbol) {
    159       var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(symbol));
    160 
    161       allowedChildSymbolsControl.SuspendRepaint = true;
    162       if (Content.GetMaximumSubtreeCount(symbol) > 0) {
    163         for (int i = 0; i < Content.GetMaximumSubtreeCount(symbol); i++) {
    164           var node = new DummySymbol("Subtree " + i).CreateTreeNode();
    165           foreach (var childSymbol in Content.GetAllowedChildSymbols(symbol, i)) {
    166             node.AddSubtree(new SymbolicExpressionTreeNode(childSymbol));
    167           }
    168           tree.Root.AddSubtree(node);
    169         }
    170       }
    171       allowedChildSymbolsControl.Tree = tree;
    172 
    173       foreach (var subtreeNode in tree.Root.Subtrees) {
    174         foreach (var allowedChildNode in subtreeNode.Subtrees) {
    175           var visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
    176           visualLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
    177         }
    178       }
    179 
    180       for (int i = Content.GetMinimumSubtreeCount(symbol); i < Content.GetMaximumSubtreeCount(symbol); i++) {
    181         var subtreeNode = tree.Root.GetSubtree(i);
    182         var visualTreeNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(subtreeNode);
    183         visualTreeNode.TextColor = Color.Gray;
    184         visualTreeNode.LineColor = Color.LightGray;
    185 
    186         var visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(tree.Root, subtreeNode);
    187         visualLine.LineColor = Color.LightGray;
    188 
    189         foreach (var allowedChildNode in subtreeNode.Subtrees) {
    190           visualTreeNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(allowedChildNode);
    191           visualTreeNode.TextColor = Color.Gray;
    192           visualTreeNode.LineColor = Color.LightGray;
    193 
    194           visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
    195           visualLine.LineColor = Color.LightGray;
    196         }
    197       }
    198 
    199       allowedChildSymbolsControl.SuspendRepaint = false;
    200       allowedChildSymbolsControl.Repaint();
    201       UpdateSelectedSymbolicExpressionTreeNodes();
    202     }
    203 
    204     private void symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
    205       if ((Control.ModifierKeys & Keys.Control) == 0)
    206         selectedSymbolicExpressionTreeNodes.Clear();
    207 
    208       VisualSymbolicExpressionTreeNode clickedNode = (VisualSymbolicExpressionTreeNode)sender;
    209       var selectedNode = clickedNode.SymbolicExpressionTreeNode;
    210       if (selectedNode.SubtreeCount == 0) {
    211         if (!selectedSymbolicExpressionTreeNodes.Contains(selectedNode))
    212           selectedSymbolicExpressionTreeNodes.Add(selectedNode);
    213         else
    214           selectedSymbolicExpressionTreeNodes.Remove(selectedNode);
    215       }
    216 
    217       UpdateSelectedSymbolicExpressionTreeNodes();
    218     }
    219 
    220     private void symbolicExpressionTreeChart_KeyDown(object sender, KeyEventArgs e) {
    221       if (e.KeyCode == Keys.Delete) {
    222         DeregisterContentEvents();
    223         var root = allowedChildSymbolsControl.Tree.Root;
    224         foreach (var node in selectedSymbolicExpressionTreeNodes) {
    225           int argIndex = root.IndexOfSubtree(node.Parent);
    226           Content.RemoveAllowedChildSymbol(root.Symbol, node.Symbol, argIndex);
    227         }
    228         RegisterContentEvents();
    229         selectedSymbolicExpressionTreeNodes.Clear();
    230         BuildAllowedChildSymbolsTree(root.Symbol);
    231       }
    232     }
    233 
     163          allowedChildSymbolsControl.Symbol = symbol;
     164        }
     165        Content.FinishedGrammarManipulation();
     166      }
     167    }
     168
     169    #region drag & drop operations
     170    private GroupSymbol parentOfDraggedSymbol;
    234171    private void symbolsTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
    235172      if (!Locked) {
    236         DataObject data = new DataObject();
    237         data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, ((TreeNode)e.Item).Tag);
    238         DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
    239       }
    240     }
     173        var treeNode = e.Item as TreeNode;
     174        if (treeNode.Parent != null) parentOfDraggedSymbol = treeNode.Parent.Tag as GroupSymbol;
     175        var data = new DataObject();
     176        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, treeNode.Tag);
     177        validDragOperation = true;
     178        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Move);
     179      }
     180    }
     181
    241182
    242183    private bool validDragOperation;
    243     private void symbolicExpressionTreeChart_DragEnter(object sender, DragEventArgs e) {
     184    private void symbolsTreeView_DragEnter(object sender, DragEventArgs e) {
    244185      validDragOperation = false;
     186      if (Content == null) return;
     187
    245188      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
    246189      var symbol = data as ISymbol;
    247       var symbols = data as IEnumerable<ISymbol>;
    248       if (symbol != null && !(symbol is IReadOnlySymbol) && Content.ContainsSymbol(symbol)) validDragOperation = true;
    249       else if (symbols != null && symbols.All(s => !(symbol is IReadOnlySymbol) && Content.ContainsSymbol(s))) validDragOperation = true;
    250     }
    251 
    252     private void symbolicExpressionTreeChart_DragOver(object sender, DragEventArgs e) {
     190      if (symbol != null && !(symbol is IReadOnlySymbol)) validDragOperation = true;
     191    }
     192    private void symbolsTreeView_DragOver(object sender, DragEventArgs e) {
    253193      e.Effect = DragDropEffects.None;
    254194      if (validDragOperation) {
    255         Point coordinates = allowedChildSymbolsControl.PointToClient(new Point(e.X, e.Y));
    256         var visualNode = allowedChildSymbolsControl.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
    257         if (visualNode != null) {
    258           var node = visualNode.SymbolicExpressionTreeNode;
    259           var root = allowedChildSymbolsControl.Tree.Root;
    260           if (root.Symbol is ProgramRootSymbol) return;
    261           if (node == root || node.Parent == root) e.Effect = DragDropEffects.Copy;
    262         }
    263       }
    264     }
    265 
    266     private void symbolicExpressionTreeChart_DragDrop(object sender, DragEventArgs e) {
    267       Point coordinates = allowedChildSymbolsControl.PointToClient(new Point(e.X, e.Y));
    268       var node = allowedChildSymbolsControl.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
    269       var root = allowedChildSymbolsControl.Tree.Root;
    270 
    271       var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
    272       var symbol = data as ISymbol;
    273       var symbols = data as IEnumerable<ISymbol>;
    274 
    275       DeregisterContentEvents();
    276       if (node.SymbolicExpressionTreeNode == root) {
    277         if (symbol != null)
    278           Content.AddAllowedChildSymbol(root.Symbol, symbol);
    279         else if (symbols != null)
    280           foreach (var s in symbols) Content.AddAllowedChildSymbol(root.Symbol, s);
    281       } else {
    282         int argumentIndex = root.IndexOfSubtree(node.SymbolicExpressionTreeNode);
    283         if (symbol != null)
    284           Content.AddAllowedChildSymbol(root.Symbol, symbol, argumentIndex);
    285         else if (symbols != null)
    286           foreach (var s in symbols) Content.AddAllowedChildSymbol(root.Symbol, s, argumentIndex);
    287       }
    288       RegisterContentEvents();
    289       BuildAllowedChildSymbolsTree(root.Symbol);
    290     }
    291 
    292     private void UpdateSelectedSymbolicExpressionTreeNodes() {
    293       foreach (var node in allowedChildSymbolsControl.Tree.IterateNodesPrefix()) {
    294         var visualNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(node);
    295         if (!selectedSymbolicExpressionTreeNodes.Contains(node)) visualNode.FillColor = Color.White;
    296         else visualNode.FillColor = Color.LightSteelBlue;
    297 
    298       }
    299       allowedChildSymbolsControl.Repaint();
    300     }
    301 
    302     private RectangleF increaseMinimumSubtreeCountRectangle;
    303     private RectangleF decreaseMinimumSubtreeCountRectangle;
    304     private RectangleF increaseMaximumSubtreeCountRectangle;
    305     private RectangleF decreaseMaximumSubtreeCountRectangle;
    306     private void allowedChildSymbolsControl_Paint(object sender, PaintEventArgs e) {
    307       increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
    308       decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
    309       increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
    310       decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
    311 
    312       if (Content == null) return;
    313       if (allowedChildSymbolsControl.Tree == null) return;
    314 
    315       var rootNode = allowedChildSymbolsControl.Tree.Root;
    316       var visualRootNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(rootNode);
    317       var graphics = e.Graphics;
    318 
    319       if (rootNode.Symbol is IReadOnlySymbol) return;
    320       if (rootNode.Symbol.MinimumArity == rootNode.Symbol.MaximumArity) return;
    321 
    322       using (Pen pen = new Pen(Color.Black)) {
    323         using (Font font = new Font("Times New Roman", 8)) {
    324           var stringFormat = new StringFormat();
    325           stringFormat.Alignment = StringAlignment.Center;
    326           stringFormat.LineAlignment = StringAlignment.Center;
    327           int spacing = 5;
    328           int size = (visualRootNode.Height - spacing * 3) / 2;
    329 
    330           increaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + spacing, size, size);
    331           decreaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + size + 2 * spacing, size, size);
    332           increaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + spacing, size, size);
    333           decreaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + size + 2 * spacing, size, size);
    334 
    335           pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == Content.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
    336           graphics.DrawString("+", font, pen.Brush, increaseMinimumSubtreeCountRectangle, stringFormat);
    337           graphics.DrawRectangle(pen, Rectangle.Round(increaseMinimumSubtreeCountRectangle));
    338           if (pen.Color == Color.LightGray) increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
    339 
    340           pen.Color = Content.GetMinimumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MinimumArity ? Color.LightGray : Color.Black;
    341           graphics.DrawString("-", font, pen.Brush, decreaseMinimumSubtreeCountRectangle, stringFormat);
    342           graphics.DrawRectangle(pen, Rectangle.Round(decreaseMinimumSubtreeCountRectangle));
    343           if (pen.Color == Color.LightGray) decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
    344 
    345           pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MaximumArity ? Color.LightGray : Color.Black;
    346           graphics.DrawRectangle(pen, Rectangle.Round(increaseMaximumSubtreeCountRectangle));
    347           graphics.DrawString("+", font, pen.Brush, increaseMaximumSubtreeCountRectangle, stringFormat);
    348           if (pen.Color == Color.LightGray) increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
    349 
    350           pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == Content.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
    351           graphics.DrawRectangle(pen, Rectangle.Round(decreaseMaximumSubtreeCountRectangle));
    352           graphics.DrawString("-", font, pen.Brush, decreaseMaximumSubtreeCountRectangle, stringFormat);
    353           if (pen.Color == Color.LightGray) decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
    354         }
    355       }
    356     }
    357 
     195        GroupSymbol groupSymbol = null;
     196        Point mouse = symbolsTreeView.PointToClient(new Point(e.X, e.Y));
     197        TreeNode node = symbolsTreeView.GetNodeAt(mouse);
     198        if (node != null) groupSymbol = node.Tag as GroupSymbol;
     199        if (node != null && groupSymbol == null) groupSymbol = node.Parent.Tag as GroupSymbol;
     200        var symbol = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
     201        if (symbol == groupSymbol) return;
     202
     203        if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
     204      }
     205    }
     206    private void symbolsTreeView_DragDrop(object sender, DragEventArgs e) {
     207      var symbol = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as ISymbol;
     208
     209      GroupSymbol groupSymbol = null;
     210      Point mouse = symbolsTreeView.PointToClient(new Point(e.X, e.Y));
     211      TreeNode node = symbolsTreeView.GetNodeAt(mouse);
     212      if (node != null) groupSymbol = node.Tag as GroupSymbol;
     213      if (node != null && groupSymbol == null) groupSymbol = node.Parent.Tag as GroupSymbol;
     214
     215      Content.StartGrammarManipulation();
     216      Cloner cloner = new Cloner();
     217      var clonedSymbol = cloner.Clone(symbol);
     218      ChangeDuplicateSymbolNames(clonedSymbol);
     219
     220      if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(clonedSymbol);
     221      else Content.AddSymbol(clonedSymbol);
     222
     223      UpdateGrammerConstraintsForClonedSymbol(symbol, cloner);
     224      Content.FinishedGrammarManipulation();
     225    }
     226    #endregion
     227
     228    #region button events
    358229    private TypeSelectorDialog typeSelectorDialog;
    359230    private void addButton_Click(object sender, EventArgs e) {
     
    367238        try {
    368239          ISymbol symbol = (ISymbol)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
    369           var originalSymbolName = symbol.Name;
    370           int i = 1;
    371           while (Content.ContainsSymbol(symbol)) {
    372             symbol.Name = originalSymbolName + i;
    373             i++;
    374           }
     240          ChangeDuplicateSymbolNames(symbol);
    375241
    376242          var selectedNode = symbolsTreeView.SelectedNode;
    377           GroupSymbol groupSymbol = null;
    378           while (selectedNode != null) {
    379             groupSymbol = selectedNode.Tag as GroupSymbol;
    380             if (groupSymbol != null && Content.ContainsSymbol(groupSymbol)) break;
    381             selectedNode = selectedNode.Parent;
    382           }
    383 
    384           if (groupSymbol != null && Content.ContainsSymbol(groupSymbol)) groupSymbol.SymbolsCollection.Add(symbol);
     243          GroupSymbol groupSymbol = selectedNode.Tag as GroupSymbol;
     244          if (groupSymbol == null && selectedNode.Parent != null) groupSymbol = selectedNode.Parent.Tag as GroupSymbol;
     245
     246          if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(symbol);
    385247          else Content.AddSymbol(symbol);
    386248        }
     
    391253    }
    392254
     255    private void copyButton_Click(object sender, EventArgs e) {
     256      var symbol = symbolsTreeView.SelectedNode.Tag as ISymbol;
     257      if (symbol != null && !(symbol is IReadOnlySymbol)) {
     258        allowedChildSymbolsControl.Symbol = null;
     259        symbolDetailsViewHost.Content = null;
     260
     261        Content.StartGrammarManipulation();
     262        Cloner cloner = new Cloner();
     263        var clonedSymbol = cloner.Clone(symbol);
     264        ChangeDuplicateSymbolNames(clonedSymbol);
     265
     266        GroupSymbol groupSymbol = null;
     267        if (symbolsTreeView.SelectedNode.Parent != null) groupSymbol = symbolsTreeView.SelectedNode.Parent.Tag as GroupSymbol;
     268
     269        if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(clonedSymbol);
     270        else Content.AddSymbol(clonedSymbol);
     271
     272        UpdateGrammerConstraintsForClonedSymbol(symbol, cloner);
     273        Content.FinishedGrammarManipulation();
     274      }
     275    }
     276
    393277    private void removeButton_Click(object sender, EventArgs e) {
    394278      var symbol = symbolsTreeView.SelectedNode.Tag as ISymbol;
    395       if (symbol != null && !(symbol is IReadOnlySymbol))
     279      if (symbol != null && !(symbol is IReadOnlySymbol)) {
    396280        Content.RemoveSymbol(symbol);
    397       removeButton.Enabled = false;
    398       allowedChildSymbolsControl.Tree = null;
    399       symbolDetailsViewHost.Content = null;
     281        allowedChildSymbolsControl.Symbol = null;
     282        symbolDetailsViewHost.Content = null;
     283      }
    400284    }
    401285
     
    403287      splitContainer1.Panel2Collapsed = !showDetailsCheckBox.Checked;
    404288    }
     289    #endregion
    405290
    406291    #region helpers
     292    private void UpdateGrammerConstraintsForClonedSymbol(ISymbol symbol, Cloner cloner) {
     293      foreach (var s in symbol.Flatten().Where(x => !(x is GroupSymbol))) {
     294        if (!cloner.ClonedObjectRegistered(s)) throw new InvalidOperationException();
     295        var clone = cloner.Clone(s);
     296        Content.SetSubtreeCount(clone, Content.GetMinimumSubtreeCount(s), Content.GetMaximumSubtreeCount(s));
     297        foreach (var childSymbol in Content.GetAllowedChildSymbols(s)) {
     298          var newChildSymbol = childSymbol;
     299          if (cloner.ClonedObjectRegistered(childSymbol)) newChildSymbol = cloner.Clone(childSymbol);
     300          Content.AddAllowedChildSymbol(clone, newChildSymbol);
     301        }
     302        for (int i = 0; i < Content.GetMaximumSubtreeCount(s); i++) {
     303          foreach (var childSymbol in Content.GetAllowedChildSymbols(s, i)) {
     304            var newChildSymbol = childSymbol;
     305            if (cloner.ClonedObjectRegistered(childSymbol)) newChildSymbol = cloner.Clone(childSymbol);
     306            Content.AddAllowedChildSymbol(clone, newChildSymbol, i);
     307          }
     308        }
     309      }
     310    }
     311
     312
     313    private void ChangeDuplicateSymbolNames(ISymbol symbol) {
     314      foreach (var s in symbol.Flatten()) {
     315        var originalSymbolName = s.Name;
     316        int i = 1;
     317        while (Content.ContainsSymbol(s)) {
     318          s.Name = originalSymbolName + i;
     319          i++;
     320        }
     321      }
     322    }
     323
    407324    private IEnumerable<TreeNode> IterateSymbolTreeNodes(TreeNode node = null) {
    408325      TreeNodeCollection nodes;
     
    428345    }
    429346    #endregion
    430 
    431     private void allowedChildSymbolsControl_MouseDown(object sender, MouseEventArgs e) {
    432       if (Content == null) return;
    433       if (allowedChildSymbolsControl.Tree == null) return;
    434 
    435       var pointF = new PointF(e.X, e.Y);
    436       var rootSymbol = allowedChildSymbolsControl.Tree.Root.Symbol;
    437       int minimumSubtreeCount = Content.GetMinimumSubtreeCount(rootSymbol);
    438       int maximumSubtreecount = Content.GetMaximumSubtreeCount(rootSymbol);
    439 
    440       bool changed = true;
    441       DeregisterContentEvents();
    442       if (increaseMinimumSubtreeCountRectangle.Contains(pointF))
    443         Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount + 1, maximumSubtreecount);
    444       else if (decreaseMinimumSubtreeCountRectangle.Contains(pointF))
    445         Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount - 1, maximumSubtreecount);
    446       else if (increaseMaximumSubtreeCountRectangle.Contains(pointF))
    447         Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount + 1);
    448       else if (decreaseMaximumSubtreeCountRectangle.Contains(pointF))
    449         Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount - 1);
    450       else
    451         changed = false;
    452 
    453       if (changed) BuildAllowedChildSymbolsTree(rootSymbol);
    454       RegisterContentEvents();
    455     }
    456347  }
    457348
    458   [NonDiscoverableType]
    459   internal class DummySymbol : Symbol {
    460     private const int minimumArity = 1;
    461     private const int maximumArity = byte.MaxValue;
    462 
    463     public override int MinimumArity {
    464       get { return minimumArity; }
    465     }
    466     public override int MaximumArity {
    467       get { return maximumArity; }
    468     }
    469 
    470     public DummySymbol(DummySymbol original, Cloner cloner) : base(original, cloner) { }
    471     public DummySymbol(string name) : base(name, "DummySymbol for views") { }
    472     public override IDeepCloneable Clone(Cloner cloner) { return new DummySymbol(this, cloner); }
     349  //this class is necessary to prevent double clicks which do not fire the checkbox checked event
     350  internal class CheckBoxTreeView : TreeView {
     351    protected override void WndProc(ref Message m) {
     352      // Suppress WM_LBUTTONDBLCLK
     353      if (m.Msg == 0x203) { m.Result = IntPtr.Zero; } else base.WndProc(ref m);
     354    }
    473355  }
    474356}
Note: See TracChangeset for help on using the changeset viewer.