Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HLScript/HeuristicLab.HLScript.Views/3.3/VariableStoreView.cs @ 10881

Last change on this file since 10881 was 10358, checked in by jkarder, 11 years ago

#2136:

  • refactored HLScriptGeneration to separate outputs from different running HL scripts.
  • added persistence support for HLScripts and fixed cloning
  • added code completion for all types in the currently loaded assemblies
  • merged trunk changes
File size: 19.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Windows.Forms;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core;
31using HeuristicLab.Core.Views;
32using HeuristicLab.MainForm;
33using HeuristicLab.MainForm.WindowsForms;
34using HeuristicLab.Persistence.Core;
35using HeuristicLab.Persistence.Default.Xml;
36using HeuristicLab.PluginInfrastructure;
37
38namespace HeuristicLab.HLScript.Views {
39  [View("ItemCollection View")]
40  [Content(typeof(VariableStore), true)]
41  public partial class VariableStoreView : AsynchronousContentView {
42    protected Dictionary<string, ListViewItem> itemListViewItemMapping;
43    protected TypeSelectorDialog typeSelectorDialog;
44    protected bool validDragOperation;
45
46    public new VariableStore Content {
47      get { return (VariableStore)base.Content; }
48      set { base.Content = value; }
49    }
50
51    public ListView ItemsListView {
52      get { return variableListView; }
53    }
54
55    public VariableStoreView() {
56      InitializeComponent();
57      itemListViewItemMapping = new Dictionary<string, ListViewItem>();
58      variableListView.SmallImageList.Images.AddRange(new Image[] {
59        HeuristicLab.Common.Resources.VSImageLibrary.Error,
60        HeuristicLab.Common.Resources.VSImageLibrary.Object,
61        HeuristicLab.Common.Resources.VSImageLibrary.Nothing
62      });
63    }
64
65    protected override void Dispose(bool disposing) {
66      if (disposing) {
67        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
68        if (components != null) components.Dispose();
69      }
70      base.Dispose(disposing);
71    }
72
73    protected override void DeregisterContentEvents() {
74      Content.ItemsAdded -= Content_ItemsAdded;
75      Content.ItemsReplaced -= Content_ItemsReplaced;
76      Content.ItemsRemoved -= Content_ItemsRemoved;
77      Content.CollectionReset -= Content_CollectionReset;
78      base.DeregisterContentEvents();
79    }
80    protected override void RegisterContentEvents() {
81      base.RegisterContentEvents();
82      Content.ItemsAdded += Content_ItemsAdded;
83      Content.ItemsReplaced += Content_ItemsReplaced;
84      Content.ItemsRemoved += Content_ItemsRemoved;
85      Content.CollectionReset += Content_CollectionReset;
86    }
87
88    protected override void OnContentChanged() {
89      base.OnContentChanged();
90      variableListView.Items.Clear();
91      itemListViewItemMapping.Clear();
92      RebuildImageList();
93      if (Content != null) {
94        Caption += " (" + Content.GetType().Name + ")";
95        foreach (var item in Content)
96          AddVariable(item);
97        AdjustListViewColumnSizes();
98        SortItemsListView(SortOrder.Ascending);
99      }
100    }
101
102    protected override void SetEnabledStateOfControls() {
103      base.SetEnabledStateOfControls();
104      if (Content == null) {
105        addButton.Enabled = false;
106        sortAscendingButton.Enabled = false;
107        sortDescendingButton.Enabled = false;
108        removeButton.Enabled = false;
109        variableListView.Enabled = false;
110      } else {
111        addButton.Enabled = !Locked && !ReadOnly;
112        sortAscendingButton.Enabled = variableListView.Items.Count > 1;
113        sortDescendingButton.Enabled = variableListView.Items.Count > 1;
114        removeButton.Enabled = !Locked && !ReadOnly && variableListView.SelectedItems.Count > 0;
115        variableListView.Enabled = true;
116      }
117    }
118
119    protected virtual object CreateItem() {
120      if (typeSelectorDialog == null) {
121        typeSelectorDialog = new TypeSelectorDialog { Caption = "Select Item" };
122        typeSelectorDialog.TypeSelector.Caption = "Available Items";
123        typeSelectorDialog.TypeSelector.Configure(typeof(IItem), false, true);
124      }
125
126      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
127        try {
128          return (object)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
129        } catch (Exception ex) {
130          ErrorHandling.ShowErrorDialog(this, ex);
131        }
132      }
133      return null;
134    }
135
136    protected virtual void AddVariable(KeyValuePair<string, object> variable) {
137      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
138      string value = (variable.Value ?? "null").ToString();
139      string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
140      bool serializable = IsSerializable(variable);
141      var listViewItem = new ListViewItem(new[] { variable.Key, value, type }) { ToolTipText = GetToolTipText(variable, serializable), Tag = variable };
142      if (serializable) {
143        listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
144      } else listViewItem.ImageIndex = 0;
145      variableListView.Items.Add(listViewItem);
146      itemListViewItemMapping[variable.Key] = listViewItem;
147      sortAscendingButton.Enabled = variableListView.Items.Count > 1;
148      sortDescendingButton.Enabled = variableListView.Items.Count > 1;
149      var item = variable.Value as IItem;
150      if (item != null) item.ToStringChanged += item_ToStringChanged;
151    }
152
153    protected virtual void RemoveVariable(KeyValuePair<string, object> variable) {
154      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
155      ListViewItem listViewItem;
156      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
157        itemListViewItemMapping.Remove(variable.Key);
158        variableListView.Items.Remove(listViewItem);
159        sortAscendingButton.Enabled = variableListView.Items.Count > 1;
160        sortDescendingButton.Enabled = variableListView.Items.Count > 1;
161        var item = variable.Value as IItem;
162        if (item != null) item.ToStringChanged -= item_ToStringChanged;
163      }
164    }
165
166    protected virtual void UpdateVariable(KeyValuePair<string, object> variable) {
167      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
168      ListViewItem listViewItem;
169      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
170        string value = (variable.Value ?? "null").ToString();
171        string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
172        bool serializable = IsSerializable(variable);
173        if (serializable) {
174          listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
175        } else listViewItem.ImageIndex = 0;
176        listViewItem.SubItems[1].Text = value;
177        listViewItem.SubItems[2].Text = type;
178        listViewItem.ToolTipText = GetToolTipText(variable, serializable);
179        listViewItem.Tag = variable;
180      } else throw new ArgumentException("A variable with the specified name does not exist.", "variable");
181    }
182
183    #region ListView Events
184    protected virtual void variableListView_SelectedIndexChanged(object sender, EventArgs e) {
185      removeButton.Enabled = (Content != null) && !Locked && !ReadOnly && variableListView.SelectedItems.Count > 0;
186      AdjustListViewColumnSizes();
187    }
188    protected virtual void variableListView_KeyDown(object sender, KeyEventArgs e) {
189      if (e.KeyCode == Keys.Delete) {
190        if ((variableListView.SelectedItems.Count > 0) && !Locked && !ReadOnly) {
191          foreach (ListViewItem item in variableListView.SelectedItems)
192            Content.Remove(item.Text);
193        }
194      }
195    }
196    protected virtual void variableListView_DoubleClick(object sender, EventArgs e) {
197      if (variableListView.SelectedItems.Count == 1) {
198        var item = variableListView.SelectedItems[0].Tag as KeyValuePair<string, object>?;
199        if (item != null) {
200          var value = item.Value.Value as IContent;
201          if (value != null) {
202            IContentView view = MainFormManager.MainForm.ShowContent(value);
203            if (view != null) {
204              view.ReadOnly = ReadOnly;
205              view.Locked = Locked;
206            }
207          }
208        }
209      }
210    }
211    protected virtual void variableListView_ItemDrag(object sender, ItemDragEventArgs e) {
212      if (!Locked) {
213        var items = new List<object>();
214        foreach (ListViewItem listViewItem in variableListView.SelectedItems) {
215          var item = (KeyValuePair<string, object>)listViewItem.Tag as KeyValuePair<string, object>?;
216          if (item != null) items.Add(item.Value.Value);
217        }
218
219        if (items.Count > 0) {
220          DataObject data = new DataObject();
221          if (items.Count == 1) data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items[0]);
222          else data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items);
223          if (ReadOnly) {
224            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
225          } else {
226            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
227            if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
228              foreach (string item in items) Content.Remove(item);
229            }
230          }
231        }
232      }
233    }
234    protected virtual void variableListView_DragEnter(object sender, DragEventArgs e) {
235      validDragOperation = false;
236      if (!Locked && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is object)) {
237        validDragOperation = true;
238      } else if (!Locked && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable)) {
239        validDragOperation = true;
240        IEnumerable items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
241        foreach (object item in items)
242          validDragOperation = validDragOperation && (item is object);
243      }
244    }
245    protected virtual void variableListView_DragOver(object sender, DragEventArgs e) {
246      e.Effect = DragDropEffects.None;
247      if (validDragOperation) {
248        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
249        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
250        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
251        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
252        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
253      }
254    }
255    protected virtual void variableListView_DragDrop(object sender, DragEventArgs e) {
256      if (e.Effect != DragDropEffects.None) {
257        if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
258          IEnumerable<object> items = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<object>();
259          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
260            var cloner = new Cloner();
261            var clonedItems = new List<object>();
262            foreach (var item in items) {
263              var dc = item as IDeepCloneable;
264              clonedItems.Add(dc != null ? cloner.Clone(dc) : item);
265            }
266            items = clonedItems;
267          }
268          foreach (var item in items) {
269            string name = GenerateNewVariableName();
270            Content.Add(name, item);
271            var listViewItem = variableListView.FindItemWithText(name);
272            listViewItem.BeginEdit();
273          }
274        } else {
275          object item = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
276          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
277            var cloner = new Cloner();
278            var dc = item as IDeepCloneable;
279            if (dc != null) item = cloner.Clone(dc);
280          }
281          string name = GenerateNewVariableName();
282          Content.Add(name, item);
283          var listViewItem = variableListView.FindItemWithText(name);
284          listViewItem.BeginEdit();
285        }
286      }
287    }
288
289    private void variableListView_AfterLabelEdit(object sender, LabelEditEventArgs e) {
290      if (!string.IsNullOrEmpty(e.Label)) {
291        var variable = (KeyValuePair<string, object>)variableListView.Items[e.Item].Tag;
292        if (!Content.ContainsKey(e.Label)) {
293          Content.Remove(variable.Key);
294          Content.Add(e.Label, variable.Value);
295        }
296      }
297      e.CancelEdit = true;
298    }
299    #endregion
300
301    #region Button Events
302    protected virtual void addButton_Click(object sender, EventArgs e) {
303      object newVar = CreateItem();
304      if (newVar != null) {
305        string name = GenerateNewVariableName();
306        Content.Add(name, newVar);
307        var item = variableListView.FindItemWithText(name);
308        item.BeginEdit();
309      }
310    }
311    protected virtual void sortAscendingButton_Click(object sender, EventArgs e) {
312      SortItemsListView(SortOrder.Ascending);
313    }
314    protected virtual void sortDescendingButton_Click(object sender, EventArgs e) {
315      SortItemsListView(SortOrder.Descending);
316    }
317    protected virtual void removeButton_Click(object sender, EventArgs e) {
318      if (variableListView.SelectedItems.Count > 0) {
319        foreach (ListViewItem item in variableListView.SelectedItems)
320          Content.Remove(item.Text);
321        variableListView.SelectedItems.Clear();
322      }
323    }
324    #endregion
325
326    #region Content Events
327    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
328      if (InvokeRequired)
329        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsAdded), sender, e);
330      else {
331        foreach (var item in e.Items)
332          AddVariable(item);
333        AdjustListViewColumnSizes();
334      }
335    }
336
337    protected virtual void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
338      if (InvokeRequired)
339        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsReplaced), sender, e);
340      else {
341        foreach (var item in e.Items)
342          UpdateVariable(item);
343        AdjustListViewColumnSizes();
344      }
345    }
346
347    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
348      if (InvokeRequired)
349        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsRemoved), sender, e);
350      else {
351        foreach (var item in e.Items)
352          RemoveVariable(item);
353        RebuildImageList();
354        AdjustListViewColumnSizes();
355      }
356    }
357    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
358      if (InvokeRequired)
359        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_CollectionReset), sender, e);
360      else {
361        foreach (var item in e.OldItems)
362          RemoveVariable(item);
363        RebuildImageList();
364        foreach (var item in e.Items)
365          AddVariable(item);
366        AdjustListViewColumnSizes();
367      }
368    }
369
370    private void item_ToStringChanged(object sender, EventArgs e) {
371      foreach (ListViewItem item in variableListView.Items) {
372        var variable = item.Tag as KeyValuePair<string, object>?;
373        if (variable != null && variable.Value.Value == sender) {
374          string value = (variable.Value.Value ?? "null").ToString();
375          item.SubItems[1].Text = value;
376          item.SubItems[2].Text = variable.Value.Value.GetType().ToString();
377          item.ToolTipText = GetToolTipText(variable.Value, item.ImageIndex == 0);
378          return;
379        }
380      }
381    }
382    #endregion
383
384    #region Helpers
385    protected virtual void SortItemsListView(SortOrder sortOrder) {
386      variableListView.Sorting = SortOrder.None;
387      variableListView.Sorting = sortOrder;
388      variableListView.Sorting = SortOrder.None;
389    }
390    protected virtual void AdjustListViewColumnSizes() {
391      if (variableListView.Items.Count > 0) {
392        for (int i = 0; i < variableListView.Columns.Count; i++)
393          variableListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
394      }
395    }
396    protected virtual void RebuildImageList() {
397      variableListView.SmallImageList.Images.Clear();
398      variableListView.SmallImageList.Images.AddRange(new Image[] {
399        HeuristicLab.Common.Resources.VSImageLibrary.Error,
400        HeuristicLab.Common.Resources.VSImageLibrary.Object,
401        HeuristicLab.Common.Resources.VSImageLibrary.Nothing
402      });
403      foreach (ListViewItem listViewItem in variableListView.Items) {
404        var variable = (KeyValuePair<string, object>)listViewItem.Tag;
405        bool serializable = IsSerializable(variable);
406        if (serializable) {
407          listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
408        } else listViewItem.ImageIndex = 0;
409      }
410    }
411
412    private string GetToolTipText(KeyValuePair<string, object> variable, bool serializable) {
413      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
414      string value = (variable.Value ?? "null").ToString();
415      string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
416      string[] lines = {
417        "Name: " + variable.Key,
418        "Value: " + value,
419        "Type: " + type
420      };
421      string toolTipText = string.Join(Environment.NewLine, lines);
422      if (!serializable)
423        toolTipText += Environment.NewLine + "CAUTION: Type is not serializable!";
424      return toolTipText;
425    }
426
427    private string GenerateNewVariableName(string defaultName = "enter_name") {
428      if (Content.ContainsKey(defaultName)) {
429        int i = 1;
430        string newName;
431        do {
432          newName = defaultName + i++;
433        } while (Content.ContainsKey(newName));
434        return newName;
435      }
436      return defaultName;
437    }
438
439    private bool IsSerializable(KeyValuePair<string, object> variable) {
440      var ser = new Serializer(variable, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()), "ROOT", true);
441      try {
442        return ser.Count() > 0;
443      } catch (PersistenceException) {
444        return false;
445      }
446    }
447    #endregion
448  }
449}
Note: See TracBrowser for help on using the repository browser.