#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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.Linq; using System.Text; using System.Windows.Forms; using HeuristicLab.PluginInfrastructure; namespace HeuristicLab.PluginInfrastructure.Advanced { /// /// Wraps a ListView and adds functionality to automatically check and uncheck dependencies of plugins. /// internal partial class PluginListView : UserControl { public event ItemCheckedEventHandler ItemChecked; private IEnumerable plugins; public IEnumerable Plugins { get { return plugins; } set { plugins = value; checkedPlugins.Clear(); UpdateControls(); } } private Dictionary checkedPlugins = new Dictionary(); public IEnumerable CheckedPlugins { get { return from pair in checkedPlugins where pair.Value select pair.Key; } } public PluginListView() { InitializeComponent(); } public void CheckPlugin(IPluginDescription plugin) { MarkPluginChecked(plugin); listView.CheckItems(new IPluginDescription[] { plugin }.Select(x => FindItemsForPlugin(x).Single())); } private void UpdateControls() { if (plugins != null) { listView.Items.Clear(); listView.SuppressItemCheckedEvents = true; foreach (var plugin in plugins) { listView.Items.Add(CreateListViewItem(plugin)); } foreach (ColumnHeader column in listView.Columns) column.Width = -1; listView.SuppressItemCheckedEvents = false; } } private ListViewItem CreateListViewItem(IPluginDescription plugin) { var item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString() }); item.Checked = checkedPlugins.ContainsKey(plugin) ? checkedPlugins[plugin] : false; item.Tag = plugin; return item; } private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) { List modifiedPlugins = new List(); if (e.Item.Checked) { foreach (ListViewItem item in listView.SelectedItems) { var plugin = (IPluginDescription)item.Tag; // also check all dependencies MarkPluginChecked(plugin); if (!modifiedPlugins.Contains(plugin)) modifiedPlugins.Add(plugin); foreach (var dep in GetAllDependencies(plugin)) { MarkPluginChecked(dep); if (!modifiedPlugins.Contains(dep)) modifiedPlugins.Add(dep); } } listView.CheckItems(modifiedPlugins.Select(x => FindItemsForPlugin(x).Single())); OnItemChecked(e); } else { foreach (ListViewItem item in listView.SelectedItems) { var plugin = (IPluginDescription)item.Tag; // also uncheck all dependent plugins MarkPluginUnchecked(plugin); if (!modifiedPlugins.Contains(plugin)) modifiedPlugins.Add(plugin); foreach (var dep in GetAllDependents(plugin)) { MarkPluginUnchecked(dep); if (!modifiedPlugins.Contains(dep)) modifiedPlugins.Add(dep); } } listView.UncheckItems(modifiedPlugins.Select(x => FindItemsForPlugin(x).Single())); OnItemChecked(e); } } private void MarkPluginChecked(IPluginDescription plugin) { checkedPlugins[plugin] = true; } private void MarkPluginUnchecked(IPluginDescription plugin) { checkedPlugins[plugin] = false; } private IEnumerable FindItemsForPlugin(IPluginDescription plugin) { return from item in listView.Items.OfType() let p = item.Tag as IPluginDescription where p.Name == plugin.Name where p.Version == plugin.Version select item; } private IEnumerable GetAllDependents(IPluginDescription plugin) { return from p in plugins let matchingEntries = from dep in GetAllDependencies(p) where dep.Name == plugin.Name where dep.Version == plugin.Version select dep where matchingEntries.Any() select p; } private IEnumerable GetAllDependencies(IPluginDescription plugin) { HashSet yieldedPlugins = new HashSet(); foreach (var dep in plugin.Dependencies) { foreach (var recDep in GetAllDependencies(dep)) { if (!yieldedPlugins.Contains(recDep)) { yieldedPlugins.Add(recDep); yield return recDep; } } if (!yieldedPlugins.Contains(dep)) { yieldedPlugins.Add(dep); yield return dep; } } } private void OnItemChecked(ItemCheckedEventArgs e) { if (ItemChecked != null) ItemChecked(this, e); } } }