#region License Information
/* HeuristicLab
* Copyright (C) 2002-2018 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
}
}