using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using HeuristicLab.Persistence.Core; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Persistence.Interfaces; using System.Text; using HeuristicLab.Persistence.Default.Decomposers; namespace HeuristicLab.Persistence.GUI { public partial class PersistenceConfigurationForm : Form { private readonly Dictionary formatterTable; private readonly Dictionary reverseFormatterTable; private readonly Dictionary typeNameTable; private readonly Dictionary reverseTypeNameTable; public PersistenceConfigurationForm() { InitializeComponent(); formatterTable = new Dictionary(); reverseFormatterTable = new Dictionary(); typeNameTable = new Dictionary(); reverseTypeNameTable = new Dictionary(); initializeDecomposerList(); initializeFormatterPages(); //ConfigurationService.Instance.DefineConfiguration( // XmlFormat.Instance, // new Configuration( // new Dictionary {{typeof (bool), new FakeBoolean2XmlFormatter()}}, // new List{new ArrayDecomposer(), new DictionaryDecomposer()})); initializeFromConfigurationService(); } private void initializeFromConfigurationService() { foreach ( IFormat format in ConfigurationService.Instance.Formatters.Keys ) { Configuration config = ConfigurationService.Instance.GetConfiguration(format); foreach (ListViewItem item in decomposerList.Items) { if (item != null) { string name = item.Tag.GetType().AssemblyQualifiedName; item.Checked = config.Decomposers.Count( d => d.GetType().AssemblyQualifiedName == name) > 0; } } foreach ( TabPage page in formatterTabs.TabPages ) { if (page.Tag == format) { DataGridView gridView = (DataGridView)page.Controls.Find("GridView", false)[0]; foreach ( DataGridViewRow row in gridView.Rows ) { if (row.Cells["Type"] != null) { IFormatter formatter = config.GetFormatter(typeNameTable[(string) row.Cells["Type"].Value]); if (formatter == null) { row.Cells["Active"].Value = false; } else { foreach (var pair in formatterTable) { if ( pair.Value.GetType().AssemblyQualifiedName == formatter.GetType().AssemblyQualifiedName ) { row.Cells["Formatter"].Value = pair.Key; row.Cells["Active"].Value = true; break; } } } } } } } } } private void initializeFormatterPages() { formatterTabs.TabPages.Clear(); foreach ( var formats in ConfigurationService.Instance.Formatters ) { TabPage page = new TabPage(formats.Key.Name) {Tag = formats.Key}; formatterTabs.TabPages.Add(page); DataGridView gridView = new DataGridView { Name = "GridView", Dock = DockStyle.Fill, EditMode = DataGridViewEditMode.EditOnEnter, AllowUserToAddRows = false, AllowUserToDeleteRows = false, AllowUserToResizeRows = false, AllowUserToOrderColumns = true, }; gridView.CellValueChanged += gridView_CellValueChanged; gridView.Columns.Add(new DataGridViewTextBoxColumn { Name = "Type", ReadOnly = true, AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill }); gridView.Columns.Add(new DataGridViewCheckBoxColumn { Name = "Active", AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells}); gridView.Columns.Add(new DataGridViewComboBoxColumn { Name = "Formatter", AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill}); page.Controls.Add(gridView); fillDataGrid(gridView, formats.Value); } } private void fillDataGrid(DataGridView gridView, IEnumerable formatters) { updateNameTables(formatters); Dictionary> formatterMap = createFormatterMap(formatters); foreach ( var formatterMapping in formatterMap ) { var row = gridView.Rows[gridView.Rows.Add()]; row.Cells["Type"].Value = formatterMapping.Key; row.Cells["Active"].ToolTipText = formatterMapping.Key; row.Cells["Formatter"].Value = true; var comboBoxCell = (DataGridViewComboBoxCell) row.Cells[2]; foreach ( var formatter in formatterMapping.Value ) { comboBoxCell.Items.Add(formatter); } comboBoxCell.Value = comboBoxCell.Items[0]; comboBoxCell.ToolTipText = comboBoxCell.Items[0].ToString(); if (comboBoxCell.Items.Count == 1) { comboBoxCell.ReadOnly = true; comboBoxCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing; } } } private Dictionary> createFormatterMap(IEnumerable formatters) { var formatterMap = new Dictionary>(); foreach (var formatter in formatters) { string formatterName = reverseFormatterTable[formatter]; string typeName = reverseTypeNameTable[formatter.Type]; if (!formatterMap.ContainsKey(typeName)) formatterMap.Add(typeName, new List()); formatterMap[typeName].Add(formatterName); } return formatterMap; } private void updateNameTables(IEnumerable formatters) { foreach (var formatter in formatters) { string formatterName = formatter.GetType().Name; if (formatterTable.ContainsKey(formatterName)) { IFormatter otherFormatter = formatterTable[formatterName]; formatterTable.Remove(formatterName); reverseFormatterTable.Remove(otherFormatter); formatterTable.Add(otherFormatter.GetType().FullName, otherFormatter); reverseFormatterTable.Add(otherFormatter, otherFormatter.GetType().FullName); formatterName = formatter.GetType().FullName; } formatterTable.Add(formatterName, formatter); reverseFormatterTable.Add(formatter, formatterName); string typeName = formatter.Type.IsGenericType ? formatter.Type.SimpleFullName() : formatter.Type.Name; if (typeNameTable.ContainsKey(typeName)) { Type otherType = typeNameTable[typeName]; if (otherType != formatter.Type) { typeNameTable.Remove(typeName); reverseTypeNameTable.Remove(otherType); typeNameTable.Add(otherType.FullName, otherType); reverseTypeNameTable.Add(otherType, otherType.FullName); typeName = formatter.Type.FullName; typeNameTable.Add(typeName, formatter.Type); reverseTypeNameTable.Add(formatter.Type, typeName); } } else { typeNameTable.Add(typeName, formatter.Type); reverseTypeNameTable.Add(formatter.Type, typeName); } } } private void initializeDecomposerList() { decomposerList.Items.Clear(); foreach ( IDecomposer decomposer in ConfigurationService.Instance.Decomposers ) { var item = decomposerList.Items.Add(decomposer.GetType().Name); item.Checked = true; item.Tag = decomposer; } } void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) { UpdatePreview(); } private void decomposerList_ItemDrag(object sender, ItemDragEventArgs e) { decomposerList.DoDragDrop(decomposerList.SelectedItems, DragDropEffects.Move); } private void decomposerList_DragEnter(object sender, DragEventArgs e) { if ( e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection).FullName)) { e.Effect = DragDropEffects.Move; } } private void decomposerList_DragDrop(object sender, DragEventArgs e) { if (decomposerList.SelectedItems.Count == 0) { return; } Point cp = decomposerList.PointToClient(new Point(e.X, e.Y)); ListViewItem targetItem = decomposerList.GetItemAt(cp.X, cp.Y); if (targetItem == null) return; int targetIndex = targetItem.Index; var selectedItems = new List(decomposerList.SelectedItems.Cast()); int i = 0; foreach ( ListViewItem dragItem in selectedItems ) { if (targetIndex == dragItem.Index) return; if (dragItem.Index < targetIndex) { decomposerList.Items.Insert(targetIndex + 1, (ListViewItem) dragItem.Clone()); } else { decomposerList.Items.Insert(targetIndex + i, (ListViewItem)dragItem.Clone()); } decomposerList.Items.Remove(dragItem); i++; } UpdatePreview(); } private void decomposerList_Resize(object sender, EventArgs e) { DecomposersColumn.Width = decomposerList.Width - 4; } private IEnumerable GetDecomposers() { List decomposers = new List(); foreach ( ListViewItem item in decomposerList.Items ) { if (item != null && item.Checked) decomposers.Add((IDecomposer) item.Tag); } return decomposers; } private void UpdatePreview() { checkBox.Items.Clear(); IFormat activeFormat = (IFormat)formatterTabs.SelectedTab.Tag; if (activeFormat != null) { foreach (var formatter in GetCurrentConfiguration(activeFormat).Formatters) { checkBox.Items.Add(formatter.GetType().Name + " (F)"); } } foreach (var decomposer in GetDecomposers()) checkBox.Items.Add(decomposer.GetType().Name + " (D)"); } private void decomposerList_ItemChecked(object sender, ItemCheckedEventArgs e) { UpdatePreview(); } public Configuration GetCurrentConfiguration(IFormat format) { Dictionary formatters = new Dictionary(); foreach ( TabPage page in formatterTabs.TabPages ) { if ( page.Text == format.Name ) { Control[] controls = page.Controls.Find("GridView", false); if (controls.Length == 1) { foreach (DataGridViewRow row in ((DataGridView) controls[0]).Rows) { if ( row.Cells["Type"].Value != null && row.Cells["Active"].Value != null && row.Cells["Formatter"].Value != null && (bool)row.Cells["Active"].Value == true ) { formatters.Add( typeNameTable[(string)row.Cells["Type"].Value], formatterTable[(string)row.Cells["Formatter"].Value]); } } } } } return new Configuration(formatters, GetDecomposers()); } private void updateButton_Click(object sender, EventArgs e) { IFormat format = (IFormat)formatterTabs.SelectedTab.Tag; if (format != null) ConfigurationService.Instance.DefineConfiguration( format, GetCurrentConfiguration(format)); } } [EmptyStorableClass] public class FakeBoolean2XmlFormatter : IFormatter { public Type Type { get { return typeof (Boolean); } } public IFormat Format { get { return XmlFormat.Instance; } } public object DoFormat(object o) { return null; } public object Parse(object o) { return null; } } [EmptyStorableClass] public class Int2XmlFormatter: IFormatter { public Type Type { get { return typeof (int); } } public IFormat Format { get { return XmlFormat.Instance; } } public object DoFormat(object o) { return null; } public object Parse(object o) { return null; } } public static class TypeFormatter { public static string SimpleFullName(this Type type) { StringBuilder sb = new StringBuilder(); SimpleFullName(type, sb); return sb.ToString(); } private static void SimpleFullName(Type type, StringBuilder sb) { if (type.IsGenericType) { sb.Append(type.Name, 0, type.Name.LastIndexOf('`')); sb.Append("<"); foreach (Type t in type.GetGenericArguments()) { SimpleFullName(t, sb); sb.Append(", "); } sb.Remove(sb.Length - 2, 2); sb.Append(">"); } else { sb.Append(type.Name); } } } }