Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 10332 was 10332, checked in by jkarder, 10 years ago

#2136: added prototype of a scripting environment

File size: 17.8 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.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33using HeuristicLab.PluginInfrastructure;
34
35namespace HeuristicLab.HLScript.Views {
36  [View("ItemCollection View")]
37  [Content(typeof(VariableStore), true)]
38  public partial class VariableStoreView : AsynchronousContentView {
39    protected Dictionary<string, ListViewItem> itemListViewItemMapping;
40    protected TypeSelectorDialog typeSelectorDialog;
41    protected bool validDragOperation;
42
43    public new VariableStore Content {
44      get { return (VariableStore)base.Content; }
45      set { base.Content = value; }
46    }
47
48    public ListView ItemsListView {
49      get { return variableListView; }
50    }
51
52    public VariableStoreView() {
53      InitializeComponent();
54      itemListViewItemMapping = new Dictionary<string, ListViewItem>();
55    }
56
57    protected override void Dispose(bool disposing) {
58      if (disposing) {
59        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
60        if (components != null) components.Dispose();
61      }
62      base.Dispose(disposing);
63    }
64
65    protected override void DeregisterContentEvents() {
66      Content.ItemsAdded -= Content_ItemsAdded;
67      Content.ItemsReplaced -= Content_ItemsReplaced;
68      Content.ItemsRemoved -= Content_ItemsRemoved;
69      Content.CollectionReset -= Content_CollectionReset;
70      base.DeregisterContentEvents();
71    }
72    protected override void RegisterContentEvents() {
73      base.RegisterContentEvents();
74      Content.ItemsAdded += Content_ItemsAdded;
75      Content.ItemsReplaced += Content_ItemsReplaced;
76      Content.ItemsRemoved += Content_ItemsRemoved;
77      Content.CollectionReset += Content_CollectionReset;
78    }
79
80    protected override void OnContentChanged() {
81      base.OnContentChanged();
82      variableListView.Items.Clear();
83      itemListViewItemMapping.Clear();
84      RebuildImageList();
85      if (Content != null) {
86        Caption += " (" + Content.GetType().Name + ")";
87        foreach (var item in Content)
88          AddVariable(item);
89        AdjustListViewColumnSizes();
90        SortItemsListView(SortOrder.Ascending);
91      }
92    }
93
94    protected override void SetEnabledStateOfControls() {
95      base.SetEnabledStateOfControls();
96      if (Content == null) {
97        addButton.Enabled = false;
98        sortAscendingButton.Enabled = false;
99        sortDescendingButton.Enabled = false;
100        removeButton.Enabled = false;
101        variableListView.Enabled = false;
102      } else {
103        addButton.Enabled = /*!Content.IsReadOnly &&*/ !ReadOnly;
104        sortAscendingButton.Enabled = variableListView.Items.Count > 1;
105        sortDescendingButton.Enabled = variableListView.Items.Count > 1;
106        removeButton.Enabled = /*!Content.IsReadOnly &&*/ !ReadOnly && variableListView.SelectedItems.Count > 0;
107        variableListView.Enabled = true;
108      }
109    }
110
111    protected virtual object CreateItem() {
112      if (typeSelectorDialog == null) {
113        typeSelectorDialog = new TypeSelectorDialog { Caption = "Select Item" };
114        typeSelectorDialog.TypeSelector.Caption = "Available Items";
115        typeSelectorDialog.TypeSelector.Configure(typeof(IItem), false, true);
116      }
117
118      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
119        try {
120          return (object)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
121        } catch (Exception ex) {
122          ErrorHandling.ShowErrorDialog(this, ex);
123        }
124      }
125      return null;
126    }
127
128    protected virtual void AddVariable(KeyValuePair<string, object> variable) {
129      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
130      string value = (variable.Value ?? "null").ToString();
131      string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
132      var listViewItem = new ListViewItem(new[] { variable.Key, value, type }) { ToolTipText = GetToolTipText(variable), Tag = variable };
133      variableListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Object);
134      listViewItem.ImageIndex = variableListView.SmallImageList.Images.Count - 1;
135      variableListView.Items.Add(listViewItem);
136      itemListViewItemMapping[variable.Key] = listViewItem;
137      sortAscendingButton.Enabled = variableListView.Items.Count > 1;
138      sortDescendingButton.Enabled = variableListView.Items.Count > 1;
139      var item = variable.Value as IItem;
140      if (item != null) item.ToStringChanged += item_ToStringChanged;
141    }
142
143    protected virtual void RemoveVariable(KeyValuePair<string, object> variable) {
144      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
145      ListViewItem listViewItem;
146      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
147        itemListViewItemMapping.Remove(variable.Key);
148        variableListView.Items.Remove(listViewItem);
149        sortAscendingButton.Enabled = variableListView.Items.Count > 1;
150        sortDescendingButton.Enabled = variableListView.Items.Count > 1;
151        var item = variable.Value as IItem;
152        if (item != null) item.ToStringChanged -= item_ToStringChanged;
153      }
154    }
155
156    protected virtual void UpdateVariable(KeyValuePair<string, object> variable) {
157      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
158      ListViewItem listViewItem;
159      if (itemListViewItemMapping.TryGetValue(variable.Key, out listViewItem)) {
160        string value = (variable.Value ?? "null").ToString();
161        string type = variable.Value == null ? "null" : variable.Value.GetType().ToString();
162        listViewItem.SubItems[1].Text = value;
163        listViewItem.SubItems[2].Text = type;
164        listViewItem.ToolTipText = GetToolTipText(variable);
165        listViewItem.Tag = variable;
166      } else throw new ArgumentException("A variable with the specified name does not exist.", "variable");
167    }
168
169    #region ListView Events
170    protected virtual void variableListView_SelectedIndexChanged(object sender, EventArgs e) {
171      removeButton.Enabled = (Content != null) /*&& !Content.IsReadOnly*/ && !ReadOnly && variableListView.SelectedItems.Count > 0;
172      AdjustListViewColumnSizes();
173    }
174    protected virtual void variableListView_KeyDown(object sender, KeyEventArgs e) {
175      if (e.KeyCode == Keys.Delete) {
176        if ((variableListView.SelectedItems.Count > 0) /*&& !Content.IsReadOnly*/ && !ReadOnly) {
177          foreach (ListViewItem item in variableListView.SelectedItems)
178            Content.Remove(item.Text);
179        }
180      }
181    }
182    protected virtual void variableListView_DoubleClick(object sender, EventArgs e) {
183      if (variableListView.SelectedItems.Count == 1) {
184        var item = variableListView.SelectedItems[0].Tag as KeyValuePair<string, object>?;
185        if (item != null) {
186          var value = item.Value.Value as IContent;
187          if (value != null) {
188            IContentView view = MainFormManager.MainForm.ShowContent(value);
189            if (view != null) {
190              view.ReadOnly = ReadOnly;
191              view.Locked = Locked;
192            }
193          }
194        }
195      }
196    }
197    protected virtual void variableListView_ItemDrag(object sender, ItemDragEventArgs e) {
198      if (!Locked) {
199        var items = new List<object>();
200        foreach (ListViewItem listViewItem in variableListView.SelectedItems) {
201          var item = (KeyValuePair<string, object>)listViewItem.Tag as KeyValuePair<string, object>?;
202          if (item != null) items.Add(item.Value.Value);
203        }
204
205        if (items.Count > 0) {
206          DataObject data = new DataObject();
207          if (items.Count == 1) data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items[0]);
208          else data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items);
209          if (/*Content.IsReadOnly ||*/ ReadOnly) {
210            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
211          } else {
212            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
213            if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
214              foreach (string item in items) Content.Remove(item);
215            }
216          }
217        }
218      }
219    }
220    protected virtual void variableListView_DragEnter(object sender, DragEventArgs e) {
221      validDragOperation = false;
222      if (/*!Content.IsReadOnly &&*/ !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is object)) {
223        validDragOperation = true;
224      } else if (/*!Content.IsReadOnly &&*/ !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable)) {
225        validDragOperation = true;
226        IEnumerable items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
227        foreach (object item in items)
228          validDragOperation = validDragOperation && (item is object);
229      }
230    }
231    protected virtual void variableListView_DragOver(object sender, DragEventArgs e) {
232      e.Effect = DragDropEffects.None;
233      if (validDragOperation) {
234        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
235        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
236        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
237        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
238        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
239      }
240    }
241    protected virtual void variableListView_DragDrop(object sender, DragEventArgs e) {
242      if (e.Effect != DragDropEffects.None) {
243        if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
244          IEnumerable<object> items = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<object>();
245          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
246            var cloner = new Cloner();
247            var clonedItems = new List<object>();
248            foreach (var item in items) {
249              var dc = item as IDeepCloneable;
250              clonedItems.Add(dc != null ? cloner.Clone(dc) : item);
251            }
252            items = clonedItems;
253          }
254          foreach (var item in items) {
255            string name = GenerateNewVariableName();
256            Content.Add(name, item);
257            var listViewItem = variableListView.FindItemWithText(name);
258            listViewItem.BeginEdit();
259          }
260        } else {
261          object item = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
262          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
263            var cloner = new Cloner();
264            var dc = item as IDeepCloneable;
265            if (dc != null) item = cloner.Clone(dc);
266          }
267          string name = GenerateNewVariableName();
268          Content.Add(name, item);
269          var listViewItem = variableListView.FindItemWithText(name);
270          listViewItem.BeginEdit();
271        }
272      }
273    }
274
275    private void variableListView_AfterLabelEdit(object sender, LabelEditEventArgs e) {
276      if (!string.IsNullOrEmpty(e.Label)) {
277        var variable = (KeyValuePair<string, object>)variableListView.Items[e.Item].Tag;
278        if (!Content.ContainsKey(e.Label)) {
279          Content.Remove(variable.Key);
280          Content.Add(e.Label, variable.Value);
281        }
282      }
283      e.CancelEdit = true;
284    }
285    #endregion
286
287    #region Button Events
288    protected virtual void addButton_Click(object sender, EventArgs e) {
289      object newVar = CreateItem();
290      if (newVar != null) {
291        string name = GenerateNewVariableName();
292        Content.Add(name, newVar);
293        var item = variableListView.FindItemWithText(name);
294        item.BeginEdit();
295      }
296    }
297    protected virtual void sortAscendingButton_Click(object sender, EventArgs e) {
298      SortItemsListView(SortOrder.Ascending);
299    }
300    protected virtual void sortDescendingButton_Click(object sender, EventArgs e) {
301      SortItemsListView(SortOrder.Descending);
302    }
303    protected virtual void removeButton_Click(object sender, EventArgs e) {
304      if (variableListView.SelectedItems.Count > 0) {
305        foreach (ListViewItem item in variableListView.SelectedItems)
306          Content.Remove(item.Text);
307        variableListView.SelectedItems.Clear();
308      }
309    }
310    #endregion
311
312    #region Content Events
313    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
314      if (InvokeRequired)
315        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsAdded), sender, e);
316      else {
317        foreach (var item in e.Items)
318          AddVariable(item);
319        AdjustListViewColumnSizes();
320      }
321    }
322
323    protected virtual void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
324      if (InvokeRequired)
325        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsReplaced), sender, e);
326      else {
327        foreach (var item in e.Items)
328          UpdateVariable(item);
329        AdjustListViewColumnSizes();
330      }
331    }
332
333    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
334      if (InvokeRequired)
335        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_ItemsRemoved), sender, e);
336      else {
337        foreach (var item in e.Items)
338          RemoveVariable(item);
339        RebuildImageList();
340        AdjustListViewColumnSizes();
341      }
342    }
343    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, object>> e) {
344      if (InvokeRequired)
345        Invoke(new CollectionItemsChangedEventHandler<KeyValuePair<string, object>>(Content_CollectionReset), sender, e);
346      else {
347        foreach (var item in e.OldItems)
348          RemoveVariable(item);
349        RebuildImageList();
350        foreach (var item in e.Items)
351          AddVariable(item);
352        AdjustListViewColumnSizes();
353      }
354    }
355
356    private void item_ToStringChanged(object sender, EventArgs e) {
357      foreach (ListViewItem item in variableListView.Items) {
358        var variable = item.Tag as KeyValuePair<string, object>?;
359        if (variable != null && variable.Value.Value == sender) {
360          string value = (variable.Value.Value ?? "null").ToString();
361          item.SubItems[1].Text = value;
362          item.SubItems[2].Text = variable.Value.Value.GetType().ToString();
363          item.ToolTipText = GetToolTipText(variable.Value);
364          return;
365        }
366      }
367    }
368    #endregion
369
370    #region Helpers
371    protected virtual void SortItemsListView(SortOrder sortOrder) {
372      variableListView.Sorting = SortOrder.None;
373      variableListView.Sorting = sortOrder;
374      variableListView.Sorting = SortOrder.None;
375    }
376    protected virtual void AdjustListViewColumnSizes() {
377      if (variableListView.Items.Count > 0) {
378        for (int i = 0; i < variableListView.Columns.Count; i++)
379          variableListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
380      }
381    }
382    protected virtual void RebuildImageList() {
383      variableListView.SmallImageList.Images.Clear();
384      foreach (ListViewItem listViewItem in variableListView.Items) {
385        object item = listViewItem.Tag as object;
386        variableListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : HeuristicLab.Common.Resources.VSImageLibrary.Object);//item.ItemImage);
387        listViewItem.ImageIndex = variableListView.SmallImageList.Images.Count - 1;
388      }
389    }
390
391    private string GetToolTipText(KeyValuePair<string, object> variable) {
392      if (string.IsNullOrEmpty(variable.Key)) throw new ArgumentException("The variable must have a name.", "variable");
393      string value = (variable.Value ?? "null").ToString();
394      string[] lines = {
395        "Name: " + variable.Key,
396        "Value: " + value,
397        "Type: " + variable.Value.GetType()
398      };
399      return string.Join(Environment.NewLine, lines);
400    }
401
402    private string GenerateNewVariableName(string defaultName = "enter_name") {
403      if (Content.ContainsKey(defaultName)) {
404        int i = 1;
405        string newName;
406        do {
407          newName = defaultName + i++;
408        } while (Content.ContainsKey(newName));
409        return newName;
410      }
411      return defaultName;
412    }
413    #endregion
414  }
415}
Note: See TracBrowser for help on using the repository browser.