#region License Information /* HeuristicLab * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Windows.Forms; using HeuristicLab.Collections; using HeuristicLab.MainForm; namespace HeuristicLab.Core.Views { /// /// The visual represenation of . /// [View("Scope View")] [Content(typeof(Scope), true)] [Content(typeof(IScope), false)] public sealed partial class ScopeView : ItemView { private Dictionary scopeNodeTable; private Dictionary subScopesScopeTable; /// /// Gets or sets the scope to represent visually. /// /// Uses property of base class . /// No own data storage present. public new IScope Content { get { return (IScope)base.Content; } set { base.Content = value; } } /// /// Initializes a new instance of with caption "Scope" and /// property set to false. /// public ScopeView() { InitializeComponent(); scopeNodeTable = new Dictionary(); subScopesScopeTable = new Dictionary(); } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing) { if (scopesTreeView.Nodes.Count > 0) { ClearTreeNode(scopesTreeView.Nodes[0]); } if (components != null) components.Dispose(); } base.Dispose(disposing); } /// /// Updates all controls with the latest data of the model. /// /// Calls of base class . protected override void OnContentChanged() { base.OnContentChanged(); if (scopesTreeView.Nodes.Count > 0) ClearTreeNode(scopesTreeView.Nodes[0]); scopesTreeView.Nodes.Clear(); variableCollectionView.Content = null; if (Content != null) { scopesTreeView.Nodes.Add(CreateTreeNode(Content)); } } protected override void SetEnabledStateOfControls() { base.SetEnabledStateOfControls(); scopesTreeView.Enabled = Content != null; variableCollectionView.Enabled = scopesTreeView.SelectedNode != null; } #region TreeNode Management private TreeNode CreateTreeNode(IScope scope) { TreeNode node = new TreeNode(); node.Text = scope.Name; node.Tag = scope; scopeNodeTable.Add(scope, node); scope.NameChanged += new EventHandler(Scope_NameChanged); subScopesScopeTable.Add(scope.SubScopes, scope); scope.SubScopes.ItemsAdded += new CollectionItemsChangedEventHandler>(SubScopes_ItemsAdded); scope.SubScopes.ItemsRemoved += new CollectionItemsChangedEventHandler>(SubScopes_ItemsRemoved); scope.SubScopes.ItemsReplaced += new CollectionItemsChangedEventHandler>(SubScopes_ItemsReplaced); scope.SubScopes.ItemsMoved += new CollectionItemsChangedEventHandler>(SubScopes_ItemsMoved); scope.SubScopes.CollectionReset += new CollectionItemsChangedEventHandler>(SubScopes_CollectionReset); if (scope.SubScopes.Count > 0) node.Nodes.Add(new TreeNode()); return node; } private void ClearTreeNode(TreeNode node) { if (scopesTreeView.SelectedNode == node) { scopesTreeView.SelectedNode = null; UpdateVariables(); } foreach (TreeNode child in node.Nodes) ClearTreeNode(child); IScope scope = node.Tag as IScope; if (scope != null) { scope.NameChanged -= new EventHandler(Scope_NameChanged); scopeNodeTable.Remove(scope); scope.SubScopes.ItemsAdded -= new CollectionItemsChangedEventHandler>(SubScopes_ItemsAdded); scope.SubScopes.ItemsRemoved -= new CollectionItemsChangedEventHandler>(SubScopes_ItemsRemoved); scope.SubScopes.ItemsReplaced -= new CollectionItemsChangedEventHandler>(SubScopes_ItemsReplaced); scope.SubScopes.ItemsMoved -= new CollectionItemsChangedEventHandler>(SubScopes_ItemsMoved); scope.SubScopes.CollectionReset -= new CollectionItemsChangedEventHandler>(SubScopes_CollectionReset); subScopesScopeTable.Remove(scope.SubScopes); } } #endregion #region TreeView Events private void scopesTreeView_AfterSelect(object sender, TreeViewEventArgs e) { UpdateVariables(); } private void scopesTreeView_MouseDown(object sender, MouseEventArgs e) { TreeNode node = scopesTreeView.GetNodeAt(e.X, e.Y); scopesTreeView.SelectedNode = node; UpdateVariables(); } private void scopesTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) { TreeNode node = e.Node; IScope scope = (IScope)node.Tag; node.Nodes.Clear(); for (int i = 0; i < scope.SubScopes.Count; i++) node.Nodes.Add(CreateTreeNode(scope.SubScopes[i])); } private void scopesTreeView_AfterCollapse(object sender, System.Windows.Forms.TreeViewEventArgs e) { TreeNode node = e.Node; IScope scope = (IScope)node.Tag; if (node.Nodes.Count > 0) { for (int i = 0; i < node.Nodes.Count; i++) ClearTreeNode(node.Nodes[i]); node.Nodes.Clear(); node.Nodes.Add(new TreeNode()); } } private void scopesTreeView_ItemDrag(object sender, ItemDragEventArgs e) { if (!Locked) { TreeNode node = (TreeNode)e.Item; IScope scope = node.Tag as IScope; if (scope != null) { DataObject data = new DataObject(); data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, scope); DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link); } } } #endregion #region Content Events private void Scope_NameChanged(object sender, EventArgs e) { if (InvokeRequired) Invoke(new EventHandler(Scope_NameChanged), sender, e); else { IScope scope = (IScope)sender; TreeNode node = null; scopeNodeTable.TryGetValue(scope, out node); if (node != null) node.Text = scope.Name; } } private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs> e) { if (InvokeRequired) Invoke(new CollectionItemsChangedEventHandler>(SubScopes_ItemsAdded), sender, e); else { IScope parentScope = null; subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope); if (parentScope != null) { TreeNode parentNode = null; scopeNodeTable.TryGetValue(parentScope, out parentNode); if (parentNode != null) { scopesTreeView.BeginUpdate(); if (parentNode.IsExpanded) { foreach (IndexedItem item in e.Items) { TreeNode node = CreateTreeNode(item.Value); parentNode.Nodes.Insert(item.Index, node); } } else if (parentNode.Nodes.Count == 0) { parentNode.Nodes.Add(new TreeNode()); } scopesTreeView.EndUpdate(); } } } } private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs> e) { if (InvokeRequired) Invoke(new CollectionItemsChangedEventHandler>(SubScopes_ItemsRemoved), sender, e); else { IScope parentScope = null; subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope); if (parentScope != null) { TreeNode parentNode = null; scopeNodeTable.TryGetValue(parentScope, out parentNode); if (parentNode != null) { scopesTreeView.BeginUpdate(); if (parentNode.IsExpanded) { foreach (IndexedItem item in e.Items) { TreeNode node = scopeNodeTable[item.Value]; ClearTreeNode(node); node.Remove(); } } else if (parentScope.SubScopes.Count == 0) { parentNode.Nodes.Clear(); } scopesTreeView.EndUpdate(); } } } } private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs> e) { if (InvokeRequired) Invoke(new CollectionItemsChangedEventHandler>(SubScopes_ItemsReplaced), sender, e); else { IScope parentScope = null; subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope); if (parentScope != null) { TreeNode parentNode = null; scopeNodeTable.TryGetValue(parentScope, out parentNode); if (parentNode != null) { scopesTreeView.BeginUpdate(); if (parentNode.IsExpanded) { foreach (IndexedItem item in e.Items) { TreeNode node = parentNode.Nodes[item.Index]; ClearTreeNode(node); node.Remove(); node = CreateTreeNode(item.Value); parentNode.Nodes.Insert(item.Index, node); } scopesTreeView.EndUpdate(); } } } } } private void SubScopes_ItemsMoved(object sender, CollectionItemsChangedEventArgs> e) { if (InvokeRequired) Invoke(new CollectionItemsChangedEventHandler>(SubScopes_ItemsMoved), sender, e); else { IScope parentScope = null; subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope); if (parentScope != null) { TreeNode parentNode = null; scopeNodeTable.TryGetValue(parentScope, out parentNode); if (parentNode != null) { scopesTreeView.BeginUpdate(); if (parentNode.IsExpanded) { parentNode.Nodes.Clear(); foreach (IndexedItem item in e.Items) parentNode.Nodes.Insert(item.Index, scopeNodeTable[item.Value]); } scopesTreeView.EndUpdate(); } } } } private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs> e) { if (InvokeRequired) Invoke(new CollectionItemsChangedEventHandler>(SubScopes_CollectionReset), sender, e); else { IScope parentScope = null; subScopesScopeTable.TryGetValue((ScopeList)sender, out parentScope); if (parentScope != null) { TreeNode parentNode = null; scopeNodeTable.TryGetValue(parentScope, out parentNode); if (parentNode != null) { scopesTreeView.BeginUpdate(); if (parentNode.IsExpanded) { foreach (TreeNode node in parentNode.Nodes) ClearTreeNode(node); parentNode.Nodes.Clear(); foreach (IndexedItem item in e.Items) { TreeNode node = CreateTreeNode(item.Value); parentNode.Nodes.Insert(item.Index, node); } } else { parentNode.Nodes.Clear(); if (parentScope.SubScopes.Count > 0) parentNode.Nodes.Add(new TreeNode()); } scopesTreeView.EndUpdate(); } } } } #endregion #region Helpers private void UpdateVariables() { if (scopesTreeView.SelectedNode == null) { variableCollectionView.Content = null; variableCollectionView.Enabled = false; } else { variableCollectionView.Enabled = true; variableCollectionView.Content = ((IScope)scopesTreeView.SelectedNode.Tag).Variables; } } #endregion } }