Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence.GUI/3.3/PersistenceConfigurationForm.cs @ 1642

Last change on this file since 1642 was 1642, checked in by epitzer, 15 years ago

suspend layout during dynamic GUI generation (#548)

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