Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.HLScript.Views/3.3/VariableStoreView.cs @ 10480

Last change on this file since 10480 was 10401, checked in by jkarder, 11 years ago

#2136:

  • renamed some HLScript files
  • fixed a bug where variables could be renamed while a script was running
  • the complete source code is now always visible
  • removed "show generated code" feature
File size: 19.1 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        variableListView.LabelEdit = !Locked && !ReadOnly;
117      }
118    }
119
120    protected virtual object CreateItem() {
121      if (typeSelectorDialog == null) {
122        typeSelectorDialog = new TypeSelectorDialog { Caption = "Select Item" };
123        typeSelectorDialog.TypeSelector.Caption = "Available Items";
124        typeSelectorDialog.TypeSelector.Configure(typeof(IItem), false, true);
125      }
126
127      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
128        try {
129          return (object)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
130        } catch (Exception ex) {
131          ErrorHandling.ShowErrorDialog(this, ex);
132        }
133      }
134      return null;
135    }
136
137    protected virtual void AddVariable(KeyValuePair<string, object> variable) {
138      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
139      string value = (variable.Value ?? "null").ToString();
140      string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
141      bool serializable = IsSerializable(variable);
142      var listViewItem = new ListViewItem(new[] { variable.Key, value, type }) { ToolTipText = GetToolTipText(variable, serializable), Tag = variable };
143      if (serializable) {
144        listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
145      } else listViewItem.ImageIndex = 0;
146      variableListView.Items.Add(listViewItem);
147      itemListViewItemMapping[variable.Key] = listViewItem;
148      sortAscendingButton.Enabled = variableListView.Items.Count > 1;
149      sortDescendingButton.Enabled = variableListView.Items.Count > 1;
150      var item = variable.Value as IItem;
151      if (item != null) item.ToStringChanged += item_ToStringChanged;
152    }
153
154    protected virtual void RemoveVariable(KeyValuePair<string, object> variable) {
155      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
156      ListViewItem listViewItem;
157      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
158        itemListViewItemMapping.Remove(variable.Key);
159        variableListView.Items.Remove(listViewItem);
160        sortAscendingButton.Enabled = variableListView.Items.Count > 1;
161        sortDescendingButton.Enabled = variableListView.Items.Count > 1;
162        var item = variable.Value as IItem;
163        if (item != null) item.ToStringChanged -= item_ToStringChanged;
164      }
165    }
166
167    protected virtual void UpdateVariable(KeyValuePair<string, object> variable) {
168      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
169      ListViewItem listViewItem;
170      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
171        string value = (variable.Value ?? "null").ToString();
172        string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
173        bool serializable = IsSerializable(variable);
174        if (serializable) {
175          listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
176        } else listViewItem.ImageIndex = 0;
177        listViewItem.SubItems[1].Text = value;
178        listViewItem.SubItems[2].Text = type;
179        listViewItem.ToolTipText = GetToolTipText(variable, serializable);
180        listViewItem.Tag = variable;
181      } else throw new ArgumentException("A variable with the specified name does not exist.", "variable");
182    }
183
184    #region ListView Events
185    protected virtual void variableListView_SelectedIndexChanged(object sender, EventArgs e) {
186      removeButton.Enabled = (Content != null) && !Locked && !ReadOnly && variableListView.SelectedItems.Count > 0;
187      AdjustListViewColumnSizes();
188    }
189    protected virtual void variableListView_KeyDown(object sender, KeyEventArgs e) {
190      if (e.KeyCode == Keys.Delete) {
191        if ((variableListView.SelectedItems.Count > 0) && !Locked && !ReadOnly) {
192          foreach (ListViewItem item in variableListView.SelectedItems)
193            Content.Remove(item.Text);
194        }
195      }
196    }
197    protected virtual void variableListView_DoubleClick(object sender, EventArgs e) {
198      if (variableListView.SelectedItems.Count == 1) {
199        var item = variableListView.SelectedItems[0].Tag as KeyValuePair<string, object>?;
200        if (item != null) {
201          var value = item.Value.Value as IContent;
202          if (value != null) {
203            IContentView view = MainFormManager.MainForm.ShowContent(value);
204            if (view != null) {
205              view.ReadOnly = ReadOnly;
206              view.Locked = Locked;
207            }
208          }
209        }
210      }
211    }
212    protected virtual void variableListView_ItemDrag(object sender, ItemDragEventArgs e) {
213      if (!Locked) {
214        var items = new List<object>();
215        foreach (ListViewItem listViewItem in variableListView.SelectedItems) {
216          var item = (KeyValuePair<string, object>)listViewItem.Tag as KeyValuePair<string, object>?;
217          if (item != null) items.Add(item.Value.Value);
218        }
219
220        if (items.Count > 0) {
221          DataObject data = new DataObject();
222          if (items.Count == 1) data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items[0]);
223          else data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items);
224          if (ReadOnly) {
225            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
226          } else {
227            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
228            if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
229              foreach (string item in items) Content.Remove(item);
230            }
231          }
232        }
233      }
234    }
235    protected virtual void variableListView_DragEnter(object sender, DragEventArgs e) {
236      validDragOperation = false;
237      if (!Locked && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is object)) {
238        validDragOperation = true;
239      } else if (!Locked && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable)) {
240        validDragOperation = true;
241        IEnumerable items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
242        foreach (object item in items)
243          validDragOperation = validDragOperation && (item is object);
244      }
245    }
246    protected virtual void variableListView_DragOver(object sender, DragEventArgs e) {
247      e.Effect = DragDropEffects.None;
248      if (validDragOperation) {
249        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
250        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
251        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
252        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
253        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
254      }
255    }
256    protected virtual void variableListView_DragDrop(object sender, DragEventArgs e) {
257      if (e.Effect != DragDropEffects.None) {
258        if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
259          IEnumerable<object> items = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<object>();
260          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
261            var cloner = new Cloner();
262            var clonedItems = new List<object>();
263            foreach (var item in items) {
264              var dc = item as IDeepCloneable;
265              clonedItems.Add(dc != null ? cloner.Clone(dc) : item);
266            }
267            items = clonedItems;
268          }
269          foreach (var item in items) {
270            string name = GenerateNewVariableName();
271            Content.Add(name, item);
272            var listViewItem = variableListView.FindItemWithText(name);
273            listViewItem.BeginEdit();
274          }
275        } else {
276          object item = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
277          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
278            var cloner = new Cloner();
279            var dc = item as IDeepCloneable;
280            if (dc != null) item = cloner.Clone(dc);
281          }
282          string name = GenerateNewVariableName();
283          Content.Add(name, item);
284          var listViewItem = variableListView.FindItemWithText(name);
285          listViewItem.BeginEdit();
286        }
287      }
288    }
289
290    private void variableListView_AfterLabelEdit(object sender, LabelEditEventArgs e) {
291      if (!string.IsNullOrEmpty(e.Label)) {
292        var variable = (KeyValuePair<string, object>)variableListView.Items[e.Item].Tag;
293        if (!Content.ContainsKey(e.Label)) {
294          Content.Remove(variable.Key);
295          Content.Add(e.Label, variable.Value);
296        }
297      }
298      e.CancelEdit = true;
299    }
300    #endregion
301
302    #region Button Events
303    protected virtual void addButton_Click(object sender, EventArgs e) {
304      object newVar = CreateItem();
305      if (newVar != null) {
306        string name = GenerateNewVariableName();
307        Content.Add(name, newVar);
308        var item = variableListView.FindItemWithText(name);
309        item.BeginEdit();
310      }
311    }
312    protected virtual void sortAscendingButton_Click(object sender, EventArgs e) {
313      SortItemsListView(SortOrder.Ascending);
314    }
315    protected virtual void sortDescendingButton_Click(object sender, EventArgs e) {
316      SortItemsListView(SortOrder.Descending);
317    }
318    protected virtual void removeButton_Click(object sender, EventArgs e) {
319      if (variableListView.SelectedItems.Count > 0) {
320        foreach (ListViewItem item in variableListView.SelectedItems)
321          Content.Remove(item.Text);
322        variableListView.SelectedItems.Clear();
323      }
324    }
325    #endregion
326
327    #region Content Events
328    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
329      if (InvokeRequired)
330        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsAdded), sender, e);
331      else {
332        foreach (var item in e.Items)
333          AddVariable(item);
334        AdjustListViewColumnSizes();
335      }
336    }
337
338    protected virtual void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
339      if (InvokeRequired)
340        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsReplaced), sender, e);
341      else {
342        foreach (var item in e.Items)
343          UpdateVariable(item);
344        AdjustListViewColumnSizes();
345      }
346    }
347
348    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
349      if (InvokeRequired)
350        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsRemoved), sender, e);
351      else {
352        foreach (var item in e.Items)
353          RemoveVariable(item);
354        RebuildImageList();
355        AdjustListViewColumnSizes();
356      }
357    }
358    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
359      if (InvokeRequired)
360        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_CollectionReset), sender, e);
361      else {
362        foreach (var item in e.OldItems)
363          RemoveVariable(item);
364        RebuildImageList();
365        foreach (var item in e.Items)
366          AddVariable(item);
367        AdjustListViewColumnSizes();
368      }
369    }
370
371    private void item_ToStringChanged(object sender, EventArgs e) {
372      foreach (ListViewItem item in variableListView.Items) {
373        var variable = item.Tag as KeyValuePair<string, object>?;
374        if (variable != null && variable.Value.Value == sender) {
375          string value = (variable.Value.Value ?? "null").ToString();
376          item.SubItems[1].Text = value;
377          item.SubItems[2].Text = variable.Value.Value.GetType().ToString();
378          item.ToolTipText = GetToolTipText(variable.Value, item.ImageIndex == 0);
379          return;
380        }
381      }
382    }
383    #endregion
384
385    #region Helpers
386    protected virtual void SortItemsListView(SortOrder sortOrder) {
387      variableListView.Sorting = SortOrder.None;
388      variableListView.Sorting = sortOrder;
389      variableListView.Sorting = SortOrder.None;
390    }
391    protected virtual void AdjustListViewColumnSizes() {
392      if (variableListView.Items.Count > 0) {
393        for (int i = 0; i < variableListView.Columns.Count; i++)
394          variableListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
395      }
396    }
397    protected virtual void RebuildImageList() {
398      variableListView.SmallImageList.Images.Clear();
399      variableListView.SmallImageList.Images.AddRange(new Image[] {
400        HeuristicLab.Common.Resources.VSImageLibrary.Error,
401        HeuristicLab.Common.Resources.VSImageLibrary.Object,
402        HeuristicLab.Common.Resources.VSImageLibrary.Nothing
403      });
404      foreach (ListViewItem listViewItem in variableListView.Items) {
405        var variable = (KeyValuePair<string, object>)listViewItem.Tag;
406        bool serializable = IsSerializable(variable);
407        if (serializable) {
408          listViewItem.ImageIndex = variable.Value == null ? 2 : 1;
409        } else listViewItem.ImageIndex = 0;
410      }
411    }
412
413    private string GetToolTipText(KeyValuePair<string, object> variable, bool serializable) {
414      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
415      string value = (variable.Value ?? "null").ToString();
416      string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
417      string[] lines = {
418        "Name: " + variable.Key,
419        "Value: " + value,
420        "Type: " + type
421      };
422      string toolTipText = string.Join(Environment.NewLine, lines);
423      if (!serializable)
424        toolTipText += Environment.NewLine + "CAUTION: Type is not serializable!";
425      return toolTipText;
426    }
427
428    private string GenerateNewVariableName(string defaultName = "enter_name") {
429      if (Content.ContainsKey(defaultName)) {
430        int i = 1;
431        string newName;
432        do {
433          newName = defaultName + i++;
434        } while (Content.ContainsKey(newName));
435        return newName;
436      }
437      return defaultName;
438    }
439
440    private bool IsSerializable(KeyValuePair<string, object> variable) {
441      var ser = new Serializer(variable, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()), "ROOT", true);
442      try {
443        return ser.Count() > 0;
444      } catch (PersistenceException) {
445        return false;
446      }
447    }
448    #endregion
449  }
450}
Note: See TracBrowser for help on using the repository browser.