source: branches/New Persistence Exploration/Persistence/HeuristicLab.Persistence.GUI/PersistenceConfigurationForm.cs @ 1414

Last change on this file since 1414 was 1414, checked in by epitzer, 12 years ago

Include decomposer configuration in dynamically created tab pages for every persistence configuration. (#506)

File size: 16.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using System.Windows.Forms;
6using HeuristicLab.Persistence.Core;
7using HeuristicLab.Persistence.Default.Xml;
8using HeuristicLab.Persistence.Interfaces;
9using System.Text;
10using HeuristicLab.Persistence.Default.Decomposers;
11
12namespace HeuristicLab.Persistence.GUI {
13
14  public partial class PersistenceConfigurationForm : Form {
15
16    private readonly Dictionary<string, IFormatter> formatterTable;
17    private readonly Dictionary<IFormatter, string> reverseFormatterTable;   
18    private readonly Dictionary<string, Type> typeNameTable;
19    private readonly Dictionary<Type, string> reverseTypeNameTable;
20
21    public PersistenceConfigurationForm() {     
22      InitializeComponent();
23      formatterTable = new Dictionary<string, IFormatter>();
24      reverseFormatterTable = new Dictionary<IFormatter, string>();
25      typeNameTable = new Dictionary<string, Type>();
26      reverseTypeNameTable = new Dictionary<Type, string>();     
27      initializeConfigPages();     
28      UpdateFromConfigurationService();
29    }
30
31    private void UpdateFormatterGrid(DataGridView formatterGrid, Configuration config) {
32      foreach (DataGridViewRow row in formatterGrid.Rows) {
33        if (row.Cells["Type"] != null) {
34          IFormatter formatter = config.GetFormatter(typeNameTable[(string)row.Cells["Type"].Value]);
35          if (formatter == null) {
36            row.Cells["Active"].Value = false;
37          } else {
38            foreach (var pair in formatterTable) {
39              if (pair.Value.GetType().FullName == formatter.GetType().FullName) {
40                row.Cells["Formatter"].Value = pair.Key;
41                row.Cells["Active"].Value = true;
42                break;
43              }
44            }
45          }
46        }
47      }
48    }
49
50    private void UpdateDecomposerList(ListView decomposerList, Configuration config) {     
51      decomposerList.Items.Clear();
52      var availableDecomposers = new Dictionary<string, IDecomposer>();
53      foreach (IDecomposer d in ConfigurationService.Instance.Decomposers) {       
54        availableDecomposers.Add(d.GetType().FullName, d);
55      }     
56      foreach (IDecomposer decomposer in config.Decomposers) {       
57        var item = decomposerList.Items.Add(decomposer.GetType().Name);       
58        item.Checked = true;
59        item.Tag = decomposer;
60        availableDecomposers.Remove(decomposer.GetType().FullName);
61      }     
62      foreach (KeyValuePair<string, IDecomposer> pair in availableDecomposers) {
63        var item = decomposerList.Items.Add(pair.Value.GetType().Name);
64        item.Checked = false;
65        item.Tag = pair.Value;
66      }
67    }   
68
69    private void UpdateFromConfigurationService() {
70      foreach (IFormat format in ConfigurationService.Instance.Formatters.Keys) {
71        Configuration config = ConfigurationService.Instance.GetConfiguration(format);       
72        UpdateFormatterGrid(
73          (DataGridView)GetControlsOnPage(format.Name, "GridView"),
74          config);       
75        UpdateDecomposerList(
76          (ListView)GetControlsOnPage(format.Name, "DecomposerList"),
77          config);
78      }
79    }   
80
81    private void initializeConfigPages() {
82      configurationTabs.TabPages.Clear();
83      foreach ( var formats in ConfigurationService.Instance.Formatters ) {       
84        TabPage page = new TabPage(formats.Key.Name) {
85          Name = formats.Key.Name,
86          Tag = formats.Key,
87        };
88        configurationTabs.TabPages.Add(page);
89        SplitContainer verticalSplit = new SplitContainer {
90          Dock = DockStyle.Fill,
91          Orientation = Orientation.Vertical,
92          BorderStyle = BorderStyle.Fixed3D,
93        };
94        page.Controls.Add(verticalSplit);
95        SplitContainer horizontalSplit = new SplitContainer {
96          Dock = DockStyle.Fill,
97          Orientation = Orientation.Horizontal,
98          BorderStyle = BorderStyle.Fixed3D,
99        };
100        verticalSplit.Panel1.Controls.Add(horizontalSplit);
101        ListView decomposerList = createDecomposerList();
102        horizontalSplit.Panel1.Controls.Add(decomposerList);
103        DataGridView gridView = createGridView();
104        verticalSplit.Panel2.Controls.Add(gridView);       
105        fillDataGrid(gridView, formats.Value);
106        ListBox checkBox = new ListBox {
107          Name = "CheckBox",
108          Dock = DockStyle.Fill,
109          Enabled = false,
110        };
111        horizontalSplit.Panel2.Controls.Add(checkBox);
112      }
113    }
114
115    private DataGridView createGridView() {
116      DataGridView gridView = new DataGridView {
117        Name = "GridView",
118        Dock = DockStyle.Fill,
119        RowHeadersVisible = false,
120        MultiSelect = false,
121        EditMode = DataGridViewEditMode.EditOnEnter,
122        AllowUserToAddRows = false,
123        AllowUserToDeleteRows = false,
124        AllowUserToResizeRows = false,
125        AllowUserToOrderColumns = true,
126      };
127      gridView.CellValueChanged += gridView_CellValueChanged;
128      gridView.Columns.Add(new DataGridViewTextBoxColumn {
129        Name = "Type", ReadOnly = true,
130        AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
131      });
132      gridView.Columns.Add(new DataGridViewCheckBoxColumn {
133        Name = "Active",
134        AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
135      });
136      gridView.Columns.Add(new DataGridViewComboBoxColumn {
137        Name = "Formatter",
138        AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
139      });
140      return gridView;
141    }
142
143    private ListView createDecomposerList() {
144      ListView decomposerList = new ListView {
145        Activation = ItemActivation.OneClick,
146        AllowDrop = true,
147        CheckBoxes = true,
148        Dock = DockStyle.Fill,
149        FullRowSelect = true,
150        GridLines = true,
151        HeaderStyle = ColumnHeaderStyle.Nonclickable,
152        Name = "DecomposerList",
153        ShowGroups = false,
154        View = View.Details
155      };
156      decomposerList.Resize += decomposerList_Resize;
157      decomposerList.ItemChecked += decomposerList_ItemChecked;
158      decomposerList.DragDrop += decomposerList_DragDrop;
159      decomposerList.DragEnter += decomposerList_DragEnter;
160      decomposerList.ItemDrag += decomposerList_ItemDrag;
161      decomposerList.Columns.Add(
162        new ColumnHeader {
163          Name = "DecomposerColumn", Text = "Decomposers",
164        });     
165      foreach (IDecomposer decomposer in ConfigurationService.Instance.Decomposers) {
166        var item = decomposerList.Items.Add(decomposer.GetType().Name);
167        item.Checked = true;
168        item.Tag = decomposer;
169      }
170      return decomposerList;
171    }
172
173    private void fillDataGrid(DataGridView gridView, IEnumerable<IFormatter> formatters) {     
174      updateNameTables(formatters);
175      Dictionary<string, List<string>> formatterMap = createFormatterMap(formatters);
176      foreach ( var formatterMapping in formatterMap ) {
177        var row = gridView.Rows[gridView.Rows.Add()];
178        row.Cells["Type"].Value = formatterMapping.Key;
179        row.Cells["Type"].ToolTipText = formatterMapping.Key;
180        row.Cells["Active"].Value = true;       
181        var comboBoxCell = (DataGridViewComboBoxCell) row.Cells["Formatter"];         
182        foreach ( var formatter in formatterMapping.Value ) {
183          comboBoxCell.Items.Add(formatter);
184        }         
185        comboBoxCell.Value = comboBoxCell.Items[0];         
186        comboBoxCell.ToolTipText = comboBoxCell.Items[0].ToString();
187        if (comboBoxCell.Items.Count == 1) {
188          comboBoxCell.ReadOnly = true;
189          comboBoxCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
190        }     
191      }
192    }
193
194    private Dictionary<string, List<string>> createFormatterMap(IEnumerable<IFormatter> formatters) {
195      var formatterMap = new Dictionary<string, List<string>>();     
196      foreach (var formatter in formatters) {
197        string formatterName = reverseFormatterTable[formatter];
198        string typeName = reverseTypeNameTable[formatter.Type];         
199        if (!formatterMap.ContainsKey(typeName))
200          formatterMap.Add(typeName, new List<string>());
201        formatterMap[typeName].Add(formatterName);
202      }
203      return formatterMap;
204    }
205
206    private void updateNameTables(IEnumerable<IFormatter> formatters) {
207      foreach (var formatter in formatters) {
208        string formatterName = formatter.GetType().Name;
209        if (formatterTable.ContainsKey(formatterName)) {
210          IFormatter otherFormatter = formatterTable[formatterName];
211          formatterTable.Remove(formatterName);
212          reverseFormatterTable.Remove(otherFormatter);
213          formatterTable.Add(otherFormatter.GetType().FullName, otherFormatter);
214          reverseFormatterTable.Add(otherFormatter, otherFormatter.GetType().FullName);
215          formatterName = formatter.GetType().FullName;
216        }
217        formatterTable.Add(formatterName, formatter);
218        reverseFormatterTable.Add(formatter, formatterName);
219
220        string typeName = formatter.Type.IsGenericType ?
221          formatter.Type.SimpleFullName() :
222          formatter.Type.Name;
223        if (typeNameTable.ContainsKey(typeName)) {
224          Type otherType = typeNameTable[typeName];
225          if (otherType != formatter.Type) {
226            typeNameTable.Remove(typeName);
227            reverseTypeNameTable.Remove(otherType);
228            typeNameTable.Add(otherType.FullName, otherType);
229            reverseTypeNameTable.Add(otherType, otherType.FullName);
230            typeName = formatter.Type.FullName;
231            typeNameTable.Add(typeName, formatter.Type);
232            reverseTypeNameTable.Add(formatter.Type, typeName);
233          }
234        } else {
235          typeNameTable.Add(typeName, formatter.Type);
236          reverseTypeNameTable.Add(formatter.Type, typeName);
237        }         
238      }
239    }   
240
241    void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
242      UpdatePreview();
243    }   
244
245    private void decomposerList_ItemDrag(object sender, ItemDragEventArgs e) {
246      ListView decomposerList = (ListView) sender;
247      decomposerList.DoDragDrop(decomposerList.SelectedItems, DragDropEffects.Move);
248    }
249
250    private void decomposerList_DragEnter(object sender, DragEventArgs e) {     
251      if ( e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection).FullName)) {
252        e.Effect = DragDropEffects.Move;
253      }
254    }
255
256    private void decomposerList_DragDrop(object sender, DragEventArgs e) {
257      ListView decomposerList = (ListView)sender;
258      if (decomposerList.SelectedItems.Count == 0) {
259        return;
260      }
261      Point cp = decomposerList.PointToClient(new Point(e.X, e.Y));     
262      ListViewItem targetItem = decomposerList.GetItemAt(cp.X, cp.Y);     
263      if (targetItem == null)
264        return;           
265      int targetIndex = targetItem.Index;     
266      var selectedItems = new List<ListViewItem>(decomposerList.SelectedItems.Cast<ListViewItem>());
267      int i = 0;
268      foreach ( ListViewItem dragItem in selectedItems ) {               
269        if (targetIndex == dragItem.Index)
270          return;
271        if (dragItem.Index < targetIndex) {
272          decomposerList.Items.Insert(targetIndex + 1, (ListViewItem) dragItem.Clone());
273        } else {
274          decomposerList.Items.Insert(targetIndex + i, (ListViewItem)dragItem.Clone());         
275        }       
276        decomposerList.Items.Remove(dragItem);
277        i++;
278      }
279      UpdatePreview();
280    }
281
282    private void decomposerList_Resize(object sender, EventArgs e) {
283      ListView decomposerList = (ListView)sender;     
284      decomposerList.Columns["DecomposerColumn"].Width = decomposerList.Width - 4;     
285    }
286   
287    private void UpdatePreview() {
288      ListBox checkBox = (ListBox)GetActiveControl("CheckBox");     
289      IFormat activeFormat = (IFormat)configurationTabs.SelectedTab.Tag;
290      if (activeFormat != null && checkBox != null ) {
291        checkBox.Items.Clear();
292        Configuration activeConfig = GetActiveConfiguration();
293        foreach (var formatter in activeConfig.Formatters) {
294          checkBox.Items.Add(formatter.GetType().Name + " (F)");
295        }
296        foreach (var decomposer in activeConfig.Decomposers)
297          checkBox.Items.Add(decomposer.GetType().Name + " (D)");     
298      }     
299    }
300
301    private void decomposerList_ItemChecked(object sender, ItemCheckedEventArgs e) {
302      UpdatePreview();
303    }
304
305    private Control GetActiveControl(string name) {
306      Control[] controls = configurationTabs.SelectedTab.Controls.Find(name, true);
307      if (controls.Length == 1) {
308        return controls[0];
309      } else {
310        return null;
311      }     
312    }
313
314    private Control GetControlsOnPage(string pageName, string name) {     
315      Control[] controls = configurationTabs.TabPages[pageName].Controls.Find(name, true);
316      if (controls.Length == 1) {
317        return controls[0];
318      } else {
319        return null;
320      }     
321    }
322
323    private Configuration GenerateConfiguration(DataGridView formatterGrid, ListView decomposerList) {
324      if (formatterGrid == null || decomposerList == null)
325        return null;
326      var formatters = new Dictionary<Type, IFormatter>();
327      foreach (DataGridViewRow row in formatterGrid.Rows) {
328        if (row.Cells["Type"].Value != null &&
329             row.Cells["Active"].Value != null &&
330             row.Cells["Formatter"].Value != null &&
331             (bool)row.Cells["Active"].Value == true) {
332          formatters.Add(
333            typeNameTable[(string)row.Cells["Type"].Value],
334            formatterTable[(string)row.Cells["Formatter"].Value]);
335        }
336      }
337      var decomposers = new List<IDecomposer>();
338      foreach (ListViewItem item in decomposerList.Items) {
339        if (item != null && item.Checked)
340          decomposers.Add((IDecomposer)item.Tag);
341      }
342      return new Configuration(formatters, decomposers);
343    }
344
345    private Configuration GetActiveConfiguration() {     
346      return GenerateConfiguration(
347        (DataGridView)GetActiveControl("GridView"),
348        (ListView)GetActiveControl("DecomposerList"));
349    }
350
351    private Configuration GetConfiguration(IFormat format) {
352       return GenerateConfiguration(
353        (DataGridView)GetControlsOnPage(format.Name, "GridView"),
354        (ListView)GetControlsOnPage(format.Name, "DecomposerList"));
355    }
356   
357    private void updateButton_Click(object sender, EventArgs e) {
358      IFormat format = (IFormat)configurationTabs.SelectedTab.Tag;
359      if (format != null)
360        ConfigurationService.Instance.DefineConfiguration(
361          format,
362          GetActiveConfiguration());
363    }   
364   
365  }
366
367  [EmptyStorableClass]
368  public class EmptyFormat : Format {
369    public override string Name { get { return "Empty"; } }
370    public static EmptyFormat Instance = new EmptyFormat();
371  }
372
373  [EmptyStorableClass]
374  public class EmptyFormatter : IFormatter {
375
376    public Type Type { get { return typeof(Type); } }
377    public IFormat  Format { get { return EmptyFormat.Instance; } }
378
379    public object DoFormat(object o) {
380     return null;
381    }
382
383    public object Parse(object o) {
384      return null;
385    }
386  }
387
388  [EmptyStorableClass]
389  public class FakeBoolean2XmlFormatter : IFormatter {   
390
391    public Type Type { get { return typeof (Boolean); } }
392
393    public IFormat Format { get { return XmlFormat.Instance; } }
394
395    public object DoFormat(object o) {
396      return null;
397    }
398
399    public object Parse(object o) {
400      return null;
401    }   
402  } 
403
404  [EmptyStorableClass]
405  public class Int2XmlFormatter: IFormatter {
406    public Type Type { get { return typeof (int);  } }
407    public IFormat Format { get { return XmlFormat.Instance; } }
408    public object DoFormat(object o) {
409      return null;
410    }
411    public object Parse(object o) {
412      return null;
413    }
414  }
415
416  public static class TypeFormatter {
417
418    public static string SimpleFullName(this Type type) {
419      StringBuilder sb = new StringBuilder();
420      SimpleFullName(type, sb);
421      return sb.ToString();
422    }
423
424    private static void SimpleFullName(Type type, StringBuilder sb) {     
425      if (type.IsGenericType) {
426        sb.Append(type.Name, 0, type.Name.LastIndexOf('`'));     
427        sb.Append("<");
428        foreach (Type t in type.GetGenericArguments()) {
429          SimpleFullName(t, sb);         
430          sb.Append(", ");
431        }
432        sb.Remove(sb.Length - 2, 2);
433        sb.Append(">");
434      } else {
435        sb.Append(type.Name);
436      }
437    }
438
439  }
440
441}
Note: See TracBrowser for help on using the repository browser.