#region License Information
/* HeuristicLab
* Copyright (C) 2002-2008 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.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using HeuristicLab.PluginInfrastructure;
namespace HeuristicLab.Core {
///
/// The visual represenation of .
///
public partial class ScopeView : ViewBase {
private Dictionary scopeNodeTable;
private Dictionary scopeExpandedTable;
///
/// Gets or sets the scope to represent visually.
///
/// Uses property of base class .
/// No own data storage present.
public IScope Scope {
get { return (IScope)Item; }
set { base.Item = value; }
}
private bool myAutomaticUpdating;
///
/// Gets information whether the scope is automatically updating.
///
public bool AutomaticUpdating {
get { return myAutomaticUpdating; }
}
///
/// Initializes a new instance of with caption "Scope" and
/// property set to false.
///
public ScopeView() {
InitializeComponent();
Caption = "Scope";
scopeNodeTable = new Dictionary();
scopeExpandedTable = new Dictionary();
myAutomaticUpdating = false;
}
///
/// Initializes a new instance of with the given .
///
/// Calls .
/// The scope to represent visually.
public ScopeView(IScope scope)
: this() {
Scope = scope;
}
///
/// Updates all controls with the latest data of the model.
///
/// Calls of base class .
protected override void UpdateControls() {
base.UpdateControls();
if (scopesTreeView.Nodes.Count > 0)
RemoveTreeNode(scopesTreeView.Nodes[0]);
scopesTreeView.SelectedNode = null;
scopesTreeView.Nodes.Clear();
if (Scope == null) {
Caption = "Scope";
scopesTreeView.Enabled = false;
} else {
Caption = Scope.Name + " (" + Scope.GetType().Name + ")";
scopesTreeView.Nodes.Add(CreateTreeNode(Scope));
scopesTreeView.Enabled = true;
}
}
private TreeNode CreateTreeNode(IScope scope) {
TreeNode node = new TreeNode();
node.Text = scope.Name;
node.Tag = scope;
scopeNodeTable.Add(scope, node);
scopeExpandedTable.Add(scope, false);
if (myAutomaticUpdating) {
scope.SubScopeAdded += new EventHandler(Scope_SubScopeAdded);
scope.SubScopeRemoved += new EventHandler(Scope_SubScopeRemoved);
scope.SubScopesReordered += new EventHandler(Scope_SubScopesReordered);
}
if (scope.SubScopes.Count > 0)
node.Nodes.Add(new TreeNode());
return node;
}
private void RemoveTreeNode(TreeNode node) {
foreach (TreeNode child in node.Nodes)
RemoveTreeNode(child);
IScope scope = node.Tag as IScope;
if ((scope != null) && (scopeNodeTable.ContainsKey(scope))) {
scopeNodeTable.Remove(scope);
scopeExpandedTable.Remove(scope);
scope.SubScopeAdded -= new EventHandler(Scope_SubScopeAdded);
scope.SubScopeRemoved -= new EventHandler(Scope_SubScopeRemoved);
scope.SubScopesReordered -= new EventHandler(Scope_SubScopesReordered);
}
}
#region TreeView Events
private void scopesTreeView_DoubleClick(object sender, EventArgs e) {
// make sure that we can't get NullPointerExceptions
if(scopesTreeView.SelectedNode != null && scopesTreeView.SelectedNode.Tag != null) {
IScope scope = (IScope)scopesTreeView.SelectedNode.Tag;
PluginManager.ControlManager.ShowControl(new VariablesScopeView(scope));
}
}
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]));
scopeExpandedTable[scope] = true;
}
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++)
RemoveTreeNode(node.Nodes[i]);
node.Nodes.Clear();
node.Nodes.Add(new TreeNode());
}
scopeExpandedTable[scope] = false;
}
private void scopesTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
TreeNode node = (TreeNode)e.Item;
IScope scope = node.Tag as IScope;
if (scope != null) {
DataObject data = new DataObject();
data.SetData("IScope", scope);
data.SetData("DragSource", scopesTreeView);
DoDragDrop(data, DragDropEffects.Copy);
}
}
#endregion
#region Context Menu Events
private void contextMenuStrip_Opening(object sender, CancelEventArgs e) {
variablesToolStripMenuItem.Enabled = false;
viewToolStripMenuItem.DropDownItems.Clear();
viewToolStripMenuItem.Enabled = false;
if (scopesTreeView.SelectedNode != null) {
variablesToolStripMenuItem.Enabled = true;
IScope scope = (IScope)scopesTreeView.SelectedNode.Tag;
foreach (IVariable variable in scope.Variables) {
if (variable.Value is IVisualizationItem) {
ToolStripMenuItem item = new ToolStripMenuItem();
item.Text = variable.Name + "...";
item.Tag = variable.Value;
item.Click += new EventHandler(showViewToolStripMenuItem_Click);
viewToolStripMenuItem.DropDownItems.Add(item);
}
}
if (viewToolStripMenuItem.DropDownItems.Count > 0)
viewToolStripMenuItem.Enabled = true;
}
}
private void automaticUpdatingToolStripMenuItem_Click(object sender, EventArgs e) {
ToolStripMenuItem item = (ToolStripMenuItem)sender;
myAutomaticUpdating = item.Checked;
if (myAutomaticUpdating)
Refresh();
}
private void refreshToolStripMenuItem_Click(object sender, EventArgs e) {
Refresh();
}
private void variablesToolStripMenuItem_Click(object sender, EventArgs e) {
IScope scope = (IScope)scopesTreeView.SelectedNode.Tag;
PluginManager.ControlManager.ShowControl(new VariablesScopeView(scope));
}
private void showViewToolStripMenuItem_Click(object sender, EventArgs e) {
IItem item = (IItem)((ToolStripMenuItem)sender).Tag;
PluginManager.ControlManager.ShowControl(item.CreateView());
}
#endregion
#region Scope Events
private delegate void ScopeDelegate(IScope scope);
private delegate void ScopeScopeIndexDelegate(IScope scope, IScope subScope, int index);
private void Scope_SubScopeAdded(object sender, ScopeIndexEventArgs e) {
IScope scope = (IScope)sender;
TreeNode node = scopeNodeTable[scope];
if (scopeExpandedTable[scope] || (scope.SubScopes.Count == 1))
AddSubScope(scope, e.Scope, e.Index);
}
private void AddSubScope(IScope scope, IScope subScope, int index) {
if (InvokeRequired) {
Invoke(new ScopeScopeIndexDelegate(AddSubScope), scope, subScope, index);
} else {
TreeNode parent = scopeNodeTable[scope];
TreeNode child;
if (parent.IsExpanded)
child = CreateTreeNode(subScope);
else
child = new TreeNode();
parent.Nodes.Insert(index, child);
}
}
private void Scope_SubScopeRemoved(object sender, ScopeIndexEventArgs e) {
IScope scope = (IScope)sender;
TreeNode node = scopeNodeTable[scope];
if (scopeExpandedTable[scope] || (scope.SubScopes.Count == 0))
RemoveSubScope(scope, e.Scope, e.Index);
}
private void RemoveSubScope(IScope scope, IScope subScope, int index) {
if (InvokeRequired) {
Invoke(new ScopeScopeIndexDelegate(RemoveSubScope), scope, subScope, index);
} else {
if (scopeNodeTable.ContainsKey(subScope)) {
TreeNode node = scopeNodeTable[subScope];
RemoveTreeNode(scopeNodeTable[subScope]);
node.Remove();
} else {
TreeNode node = scopeNodeTable[scope];
node.Nodes[0].Remove();
}
}
}
private void Scope_SubScopesReordered(object sender, EventArgs e) {
IScope scope = (IScope)sender;
TreeNode node = scopeNodeTable[scope];
if (scopeExpandedTable[scope])
ReorderSubScopes(scope);
}
private void ReorderSubScopes(IScope scope) {
if (InvokeRequired) {
Invoke(new ScopeDelegate(ReorderSubScopes), scope);
} else {
TreeNode node = scopeNodeTable[scope];
node.Nodes.Clear();
for (int i = 0; i < scope.SubScopes.Count; i++)
node.Nodes.Add(scopeNodeTable[scope.SubScopes[i]]);
}
}
#endregion
#region Mouse Events
private void scopesTreeView_MouseDown(object sender, MouseEventArgs e) {
if (e.Button != MouseButtons.Right)
return;
TreeNode clickedNode = scopesTreeView.GetNodeAt(e.X, e.Y);
if (clickedNode != null) {
scopesTreeView.SelectedNode = clickedNode;
scopesTreeView.Refresh();
}
}
#endregion
}
}