#region License Information /* HeuristicLab * Copyright (C) 2002-2019 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.Drawing; using System.Linq; using System.Windows.Forms; using HEAL.Fossil; using HeuristicLab.Persistence.Auxiliary; using HeuristicLab.Persistence.Core; using HeuristicLab.Persistence.Interfaces; namespace HeuristicLab.Persistence.GUI { public partial class PersistenceConfigurationForm : Form { private readonly Dictionary primitiveSerializersTable; private readonly Dictionary simplePrimitiveSerializersTable; private readonly Dictionary reversePrimitiveSerializersTable; private readonly Dictionary typeNameTable; private readonly Dictionary reverseTypeNameTable; private bool underConstruction; public PersistenceConfigurationForm() { InitializeComponent(); primitiveSerializersTable = new Dictionary(); simplePrimitiveSerializersTable = new Dictionary(); reversePrimitiveSerializersTable = new Dictionary(); typeNameTable = new Dictionary(); reverseTypeNameTable = new Dictionary(); underConstruction = true; InitializeTooltips(); InitializeNameTables(); initializeConfigPages(); try { ConfigurationService.Instance.LoadSettings(true); UpdateFromConfigurationService(); } catch (PersistenceException) { MessageBox.Show( "Persistence settings could not be loaded.\r\n" + "Default configurations will be used instead.", "Loading Settings Failed", MessageBoxButtons.OK, MessageBoxIcon.Information); } underConstruction = false; UpdatePreview(); } private void InitializeTooltips() { ToolTip tooltip = new ToolTip() { AutoPopDelay = 5000, InitialDelay = 1000, ReshowDelay = 500, ShowAlways = true }; tooltip.SetToolTip(resetButton, "Clear all custom configurations from memory.\r\n" + "The saved configuration will still be used next\r\n" + "time if you don't save (define) this change."); tooltip.SetToolTip(updateButton, "Define configuration for currently active format\r\n" + "and save to disk."); } private void UpdatePrimitiveSerializersGrid(DataGridView primitiveSerializersGrid, Configuration config) { foreach (DataGridViewRow row in primitiveSerializersGrid.Rows) { if (row.Cells["Type"] != null) { IPrimitiveSerializer primitiveSerializer = config.GetPrimitiveSerializer(typeNameTable[(string)row.Cells["Type"].Value]); if (primitiveSerializer == null) { row.Cells["Active"].Value = false; } else { foreach (var pair in primitiveSerializersTable) { if (pair.Value.GetType().VersionInvariantName() == primitiveSerializer.GetType().VersionInvariantName()) { row.Cells["Primitive Serializer"].Value = pair.Key; row.Cells["Active"].Value = true; break; } } } } } } private void UpdateCompositeSerializersList(ListView compositeSerializersList, Configuration config) { compositeSerializersList.SuspendLayout(); compositeSerializersList.Items.Clear(); var availableCompositeSerializers = new Dictionary(); foreach (ICompositeSerializer d in ConfigurationService.Instance.CompositeSerializers) { availableCompositeSerializers.Add(d.GetType().VersionInvariantName(), d); } foreach (ICompositeSerializer compositeSerializer in config.CompositeSerializers) { var item = compositeSerializersList.Items.Add(compositeSerializer.GetType().Name); item.Checked = true; item.Tag = compositeSerializer; availableCompositeSerializers.Remove(compositeSerializer.GetType().VersionInvariantName()); } foreach (KeyValuePair pair in availableCompositeSerializers) { var item = compositeSerializersList.Items.Add(pair.Value.GetType().Name); item.Checked = false; item.Tag = pair.Value; } compositeSerializersList.ResumeLayout(); } private void UpdateFromConfigurationService() { configurationTabs.SuspendLayout(); foreach (IFormat format in ConfigurationService.Instance.Formats) { Configuration config = ConfigurationService.Instance.GetConfiguration(format); UpdatePrimitiveSerializersGrid( (DataGridView)GetControlsOnPage(format.Name, "GridView"), config); UpdateCompositeSerializersList( (ListView)GetControlsOnPage(format.Name, "CompositeSerializersList"), config); } configurationTabs.ResumeLayout(); } private void initializeConfigPages() { configurationTabs.SuspendLayout(); configurationTabs.TabPages.Clear(); foreach (IFormat format in ConfigurationService.Instance.Formats) { List primitiveSerializers = ConfigurationService.Instance.PrimitiveSerializers[format.SerialDataType]; TabPage page = new TabPage(format.Name) { Name = format.Name, Tag = format, }; page.SuspendLayout(); configurationTabs.TabPages.Add(page); SplitContainer verticalSplit = new SplitContainer { Dock = DockStyle.Fill, Orientation = Orientation.Vertical, BorderStyle = BorderStyle.Fixed3D, }; verticalSplit.SuspendLayout(); page.Controls.Add(verticalSplit); SplitContainer horizontalSplit = new SplitContainer { Dock = DockStyle.Fill, Orientation = Orientation.Horizontal, BorderStyle = BorderStyle.Fixed3D, }; horizontalSplit.SuspendLayout(); verticalSplit.Panel1.Controls.Add(horizontalSplit); ListView compositeSerializersList = createCompsiteSerializersList(); horizontalSplit.Panel1.Controls.Add(compositeSerializersList); DataGridView gridView = createGridView(); verticalSplit.Panel2.Controls.Add(gridView); fillDataGrid(gridView, primitiveSerializers); ListBox checkBox = new ListBox { Name = "CheckBox", Dock = DockStyle.Fill, }; horizontalSplit.Panel2.Controls.Add(checkBox); horizontalSplit.ResumeLayout(); verticalSplit.ResumeLayout(); page.ResumeLayout(); } configurationTabs.ResumeLayout(); } private DataGridView createGridView() { DataGridView gridView = new DataGridView { Name = "GridView", Dock = DockStyle.Fill, RowHeadersVisible = false, MultiSelect = false, EditMode = DataGridViewEditMode.EditOnEnter, AllowUserToAddRows = false, AllowUserToDeleteRows = false, AllowUserToResizeRows = false, AllowUserToOrderColumns = true, }; gridView.SuspendLayout(); 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 = "Primitive Serializer", AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill }); gridView.ResumeLayout(); return gridView; } private ListView createCompsiteSerializersList() { ListView compositeSerializersList = new ListView { Activation = ItemActivation.OneClick, AllowDrop = true, CheckBoxes = true, Dock = DockStyle.Fill, FullRowSelect = true, GridLines = true, HeaderStyle = ColumnHeaderStyle.Nonclickable, Name = "CompositeSerializersList", ShowGroups = false, View = View.Details }; compositeSerializersList.SuspendLayout(); compositeSerializersList.Resize += compositeSerializersList_Resize; compositeSerializersList.ItemChecked += compositeSerializersList_ItemChecked; compositeSerializersList.DragDrop += compositeSerializersList_DragDrop; compositeSerializersList.DragEnter += compositeSerializersList_DragEnter; compositeSerializersList.ItemDrag += compositeSerializersList_ItemDrag; compositeSerializersList.Columns.Add( new ColumnHeader { Name = "CompositeSerializersColumn", Text = "Composite Serializer", }); foreach (ICompositeSerializer compositeSerializer in ConfigurationService.Instance.CompositeSerializers) { var item = compositeSerializersList.Items.Add(compositeSerializer.GetType().Name); item.Checked = true; item.Tag = compositeSerializer; } compositeSerializersList.ResumeLayout(); return compositeSerializersList; } private void fillDataGrid(DataGridView gridView, IEnumerable primitiveSerializers) { gridView.SuspendLayout(); Dictionary> primitiveSerializersMap = createPrimitiveSerializersMap(primitiveSerializers); foreach (var primitiveSerializersMapping in primitiveSerializersMap) { var row = gridView.Rows[gridView.Rows.Add()]; row.Cells["Type"].Value = primitiveSerializersMapping.Key; row.Cells["Type"].ToolTipText = primitiveSerializersMapping.Key; row.Cells["Active"].Value = true; var comboBoxCell = (DataGridViewComboBoxCell)row.Cells["Primitive Serializer"]; foreach (var primitiveSerializer in primitiveSerializersMapping.Value) { comboBoxCell.Items.Add(primitiveSerializer); } comboBoxCell.Value = comboBoxCell.Items[0]; comboBoxCell.ToolTipText = comboBoxCell.Items[0].ToString(); if (comboBoxCell.Items.Count == 1) { comboBoxCell.ReadOnly = true; comboBoxCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing; } } gridView.ResumeLayout(); } private Dictionary> createPrimitiveSerializersMap(IEnumerable primitiveSerializers) { var primitiveSerializersMap = new Dictionary>(); foreach (var primitiveSerializer in primitiveSerializers) { string primitiveSerializerName = reversePrimitiveSerializersTable[primitiveSerializer]; string typeName = reverseTypeNameTable[primitiveSerializer.SourceType]; if (!primitiveSerializersMap.ContainsKey(typeName)) primitiveSerializersMap.Add(typeName, new List()); primitiveSerializersMap[typeName].Add(primitiveSerializerName); } return primitiveSerializersMap; } private void InitializeNameTables() { foreach (var serialDataType in ConfigurationService.Instance.PrimitiveSerializers.Keys) { foreach (var primtiveSerializer in ConfigurationService.Instance.PrimitiveSerializers[serialDataType]) { string primitiveSerializerName = primtiveSerializer.GetType().Name; if (simplePrimitiveSerializersTable.ContainsKey(primitiveSerializerName)) { IPrimitiveSerializer otherPrimitiveSerializer = primitiveSerializersTable[primitiveSerializerName]; primitiveSerializersTable.Remove(primitiveSerializerName); reversePrimitiveSerializersTable.Remove(otherPrimitiveSerializer); primitiveSerializersTable.Add(otherPrimitiveSerializer.GetType().VersionInvariantName(), otherPrimitiveSerializer); reversePrimitiveSerializersTable.Add(otherPrimitiveSerializer, otherPrimitiveSerializer.GetType().VersionInvariantName()); primitiveSerializerName = primtiveSerializer.GetType().VersionInvariantName(); } simplePrimitiveSerializersTable[primtiveSerializer.GetType().Name] = true; primitiveSerializersTable.Add(primitiveSerializerName, primtiveSerializer); reversePrimitiveSerializersTable.Add(primtiveSerializer, primitiveSerializerName); string typeName = primtiveSerializer.SourceType.IsGenericType ? primtiveSerializer.SourceType.SimpleFullName() : primtiveSerializer.SourceType.Name; if (typeNameTable.ContainsKey(typeName)) { Type otherType = typeNameTable[typeName]; if (otherType != primtiveSerializer.SourceType) { typeNameTable.Remove(typeName); reverseTypeNameTable.Remove(otherType); typeNameTable.Add(otherType.VersionInvariantName(), otherType); reverseTypeNameTable.Add(otherType, otherType.VersionInvariantName()); typeName = primtiveSerializer.SourceType.VersionInvariantName(); typeNameTable.Add(typeName, primtiveSerializer.SourceType); reverseTypeNameTable.Add(primtiveSerializer.SourceType, typeName); } } else { typeNameTable.Add(typeName, primtiveSerializer.SourceType); reverseTypeNameTable.Add(primtiveSerializer.SourceType, typeName); } } } } private void UpdatePreview() { if (underConstruction) return; ListBox checkBox = (ListBox)GetActiveControl("CheckBox"); checkBox.SuspendLayout(); IFormat activeFormat = (IFormat)configurationTabs.SelectedTab.Tag; if (activeFormat != null && checkBox != null) { checkBox.Items.Clear(); Configuration activeConfig = GetActiveConfiguration(); foreach (var primitveSerializer in activeConfig.PrimitiveSerializers) { checkBox.Items.Add(primitveSerializer.GetType().Name + " (F)"); } foreach (var compositeSerializer in activeConfig.CompositeSerializers) checkBox.Items.Add(compositeSerializer.GetType().Name + " (D)"); } checkBox.ResumeLayout(); } void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) { UpdatePreview(); } private void compositeSerializersList_ItemDrag(object sender, ItemDragEventArgs e) { ListView compositeSerializersList = (ListView)sender; compositeSerializersList.DoDragDrop(compositeSerializersList.SelectedItems, DragDropEffects.Move); } private void compositeSerializersList_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection).FullName)) { e.Effect = DragDropEffects.Move; } } private void compositeSerializersList_DragDrop(object sender, DragEventArgs e) { ListView compositeSerializersList = (ListView)sender; if (compositeSerializersList.SelectedItems.Count == 0) { return; } Point cp = compositeSerializersList.PointToClient(new Point(e.X, e.Y)); ListViewItem targetItem = compositeSerializersList.GetItemAt(cp.X, cp.Y); if (targetItem == null) return; int targetIndex = targetItem.Index; var selectedItems = new List(compositeSerializersList.SelectedItems.Cast()); int i = 0; foreach (ListViewItem dragItem in selectedItems) { if (targetIndex == dragItem.Index) return; if (dragItem.Index < targetIndex) { compositeSerializersList.Items.Insert(targetIndex + 1, (ListViewItem)dragItem.Clone()); } else { compositeSerializersList.Items.Insert(targetIndex + i, (ListViewItem)dragItem.Clone()); } compositeSerializersList.Items.Remove(dragItem); i++; } UpdatePreview(); } private void compositeSerializersList_Resize(object sender, EventArgs e) { ListView compositeSerializersList = (ListView)sender; compositeSerializersList.Columns["CompositeSerializersColumn"].Width = compositeSerializersList.Width - 4; } private void compositeSerializersList_ItemChecked(object sender, ItemCheckedEventArgs e) { UpdatePreview(); } private Control GetActiveControl(string name) { Control[] controls = configurationTabs.SelectedTab.Controls.Find(name, true); if (controls.Length == 1) { return controls[0]; } else { return null; } } private Control GetControlsOnPage(string pageName, string name) { Control[] controls = configurationTabs.TabPages[pageName].Controls.Find(name, true); if (controls.Length == 1) { return controls[0]; } else { return null; } } private Configuration GenerateConfiguration(IFormat format, DataGridView primitiveSerializersGrid, ListView compositeSerializersList) { if (primitiveSerializersGrid == null || compositeSerializersList == null) return null; var primitiveSerializers = new List(); foreach (DataGridViewRow row in primitiveSerializersGrid.Rows) { if (row.Cells["Type"].Value != null && row.Cells["Active"].Value != null && row.Cells["Primitive Serializer"].Value != null && (bool)row.Cells["Active"].Value == true) { primitiveSerializers.Add(primitiveSerializersTable[(string)row.Cells["Primitive Serializer"].Value]); } } var compositeSerializers = new List(); foreach (ListViewItem item in compositeSerializersList.Items) { if (item != null && item.Checked) compositeSerializers.Add((ICompositeSerializer)item.Tag); } return new Configuration(format, primitiveSerializers, compositeSerializers); } private Configuration GetActiveConfiguration() { IFormat format = (IFormat)configurationTabs.SelectedTab.Tag; return GenerateConfiguration(format, (DataGridView)GetActiveControl("GridView"), (ListView)GetActiveControl("CompositeSerializersList")); } private Configuration GetConfiguration(IFormat format) { return GenerateConfiguration(format, (DataGridView)GetControlsOnPage(format.Name, "GridView"), (ListView)GetControlsOnPage(format.Name, "CompositeSerializersList")); } private void updateButton_Click(object sender, EventArgs e) { IFormat format = (IFormat)configurationTabs.SelectedTab.Tag; if (format != null) ConfigurationService.Instance.DefineConfiguration( GetActiveConfiguration()); } private void resetButton_Click(object sender, EventArgs e) { ConfigurationService.Instance.Reset(); underConstruction = true; UpdateFromConfigurationService(); underConstruction = false; UpdatePreview(); } } }