Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core.Views/3.3/ItemArrayView.cs @ 5928

Last change on this file since 5928 was 5928, checked in by swagner, 13 years ago

Prevented disappearing of runs in an optimizer when moving the optimizer up or down in an experiment (#1445)

File size: 20.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Collections;
28using HeuristicLab.MainForm;
29using HeuristicLab.MainForm.WindowsForms;
30using HeuristicLab.PluginInfrastructure;
31
32namespace HeuristicLab.Core.Views {
33  [View("ItemArray View")]
34  [Content(typeof(ItemArray<>), true)]
35  [Content(typeof(IItemArray<>), false)]
36  public partial class ItemArrayView<T> : ItemView where T : class, IItem {
37    protected Dictionary<T, List<ListViewItem>> itemListViewItemMapping;
38    protected TypeSelectorDialog typeSelectorDialog;
39    protected bool validDragOperation;
40
41    public new IItemArray<T> Content {
42      get { return (IItemArray<T>)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public ListView ItemsListView {
47      get { return itemsListView; }
48    }
49
50    public ItemArrayView() {
51      InitializeComponent();
52      itemListViewItemMapping = new Dictionary<T, List<ListViewItem>>();
53    }
54
55    protected override void Dispose(bool disposing) {
56      if (disposing) {
57        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
58        if (components != null) components.Dispose();
59      }
60      base.Dispose(disposing);
61    }
62
63    protected override void DeregisterContentEvents() {
64      Content.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsReplaced);
65      Content.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsMoved);
66      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_CollectionReset);
67      foreach (T item in itemListViewItemMapping.Keys) {
68        DeregisterItemEvents(item);
69      }
70      base.DeregisterContentEvents();
71    }
72    protected override void RegisterContentEvents() {
73      base.RegisterContentEvents();
74      Content.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsReplaced);
75      Content.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsMoved);
76      Content.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_CollectionReset);
77    }
78    protected virtual void DeregisterItemEvents(T item) {
79      item.ItemImageChanged -= new EventHandler(Item_ItemImageChanged);
80      item.ToStringChanged -= new EventHandler(Item_ToStringChanged);
81    }
82    protected virtual void RegisterItemEvents(T item) {
83      item.ItemImageChanged += new EventHandler(Item_ItemImageChanged);
84      item.ToStringChanged += new EventHandler(Item_ToStringChanged);
85    }
86
87    protected override void OnContentChanged() {
88      base.OnContentChanged();
89
90      int selectedIndex = -1;
91      if (itemsListView.SelectedItems.Count == 1) selectedIndex = itemsListView.SelectedIndices[0];
92
93      itemsListView.Items.Clear();
94      itemListViewItemMapping.Clear();
95      RebuildImageList();
96      viewHost.Content = null;
97      if (Content != null) {
98        Caption += " (" + Content.GetType().Name + ")";
99        foreach (T item in Content)
100          AddListViewItem(CreateListViewItem(item));
101        AdjustListViewColumnSizes();
102        if ((selectedIndex != -1) && (selectedIndex < itemsListView.Items.Count))
103          itemsListView.Items[selectedIndex].Selected = true;
104      }
105    }
106
107    protected override void SetEnabledStateOfControls() {
108      base.SetEnabledStateOfControls();
109      if (Content == null) {
110        addButton.Enabled = false;
111        moveUpButton.Enabled = false;
112        moveDownButton.Enabled = false;
113        removeButton.Enabled = false;
114        itemsListView.Enabled = false;
115        detailsGroupBox.Enabled = false;
116      } else {
117        addButton.Enabled = itemsListView.SelectedItems.Count > 0 &&
118                            !Content.IsReadOnly && !ReadOnly;
119        moveUpButton.Enabled = itemsListView.SelectedItems.Count == 1 &&
120                               itemsListView.SelectedIndices[0] != 0 &&
121                               !Content.IsReadOnly && !ReadOnly;
122        moveDownButton.Enabled = itemsListView.SelectedItems.Count == 1 &&
123                                 itemsListView.SelectedIndices[0] != itemsListView.Items.Count - 1 &&
124                                 !Content.IsReadOnly && !ReadOnly;
125        removeButton.Enabled = itemsListView.SelectedItems.Count > 0 &&
126                               !Content.IsReadOnly && !ReadOnly;
127        itemsListView.Enabled = true;
128        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
129      }
130    }
131
132    protected virtual T CreateItem() {
133      if (typeSelectorDialog == null) {
134        typeSelectorDialog = new TypeSelectorDialog();
135        typeSelectorDialog.Caption = "Select Item";
136        typeSelectorDialog.TypeSelector.Caption = "Available Items";
137        typeSelectorDialog.TypeSelector.Configure(typeof(T), false, true);
138      }
139
140      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
141        try {
142          return (T)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
143        }
144        catch (Exception ex) {
145          ErrorHandling.ShowErrorDialog(this, ex);
146        }
147      }
148      return null;
149    }
150    protected virtual ListViewItem CreateListViewItem(T item) {
151      ListViewItem listViewItem = new ListViewItem();
152      if (item == null) {
153        listViewItem.Text = "null";
154        itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
155        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
156      } else {
157        listViewItem.Text = item.ToString();
158        listViewItem.ToolTipText = item.ItemName + ": " + item.ItemDescription;
159        itemsListView.SmallImageList.Images.Add(item.ItemImage);
160        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
161        listViewItem.Tag = item;
162      }
163      return listViewItem;
164    }
165    protected virtual void AddListViewItem(ListViewItem listViewItem) {
166      if (listViewItem == null) throw new ArgumentNullException();
167      T item = (listViewItem.Tag as T);
168      itemsListView.Items.Add(listViewItem);
169      if (item != null) {
170        if (!itemListViewItemMapping.ContainsKey(item)) {
171          RegisterItemEvents(item);
172          itemListViewItemMapping.Add(item, new List<ListViewItem>());
173        }
174        itemListViewItemMapping[item].Add(listViewItem);
175      }
176    }
177    protected virtual void InsertListViewItem(int index, ListViewItem listViewItem) {
178      if (listViewItem == null) throw new ArgumentNullException();
179      T item = (listViewItem.Tag as T);
180      itemsListView.Items.Insert(index, listViewItem);
181      if (item != null) {
182        if (!itemListViewItemMapping.ContainsKey(item)) {
183          RegisterItemEvents(item);
184          itemListViewItemMapping.Add(item, new List<ListViewItem>());
185        }
186        itemListViewItemMapping[item].Add(listViewItem);
187      }
188    }
189    protected virtual void RemoveListViewItem(ListViewItem listViewItem) {
190      if (listViewItem == null) throw new ArgumentNullException();
191      T item = (listViewItem.Tag as T);
192      if (item != null) {
193        itemListViewItemMapping[item].Remove(listViewItem);
194        if (itemListViewItemMapping[item].Count == 0) {
195          itemListViewItemMapping.Remove(item);
196          DeregisterItemEvents(item);
197        }
198      }
199      listViewItem.Remove();
200    }
201    protected virtual void UpdateListViewItemImage(ListViewItem listViewItem) {
202      if (listViewItem == null) throw new ArgumentNullException();
203      T item = listViewItem.Tag as T;
204      int i = listViewItem.ImageIndex;
205      itemsListView.SmallImageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
206      listViewItem.ImageIndex = -1;
207      listViewItem.ImageIndex = i;
208    }
209    protected virtual void UpdateListViewItemText(ListViewItem listViewItem) {
210      if (listViewItem == null) throw new ArgumentNullException();
211      T item = listViewItem.Tag as T;
212      listViewItem.Text = item == null ? "null" : item.ToString();
213      listViewItem.ToolTipText = item == null ? string.Empty : item.ItemName + ": " + item.ItemDescription;
214    }
215    protected virtual IEnumerable<ListViewItem> GetListViewItemsForItem(T item) {
216      if (item == null) {
217        List<ListViewItem> listViewItems = new List<ListViewItem>();
218        foreach (ListViewItem listViewItem in itemsListView.Items) {
219          if (listViewItem.Tag == null) listViewItems.Add(listViewItem);
220        }
221        return listViewItems;
222      } else {
223        List<ListViewItem> listViewItems = null;
224        itemListViewItemMapping.TryGetValue(item, out listViewItems);
225        return listViewItems == null ? Enumerable.Empty<ListViewItem>() : listViewItems;
226      }
227    }
228
229    #region ListView Events
230    protected virtual void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
231      addButton.Enabled = itemsListView.SelectedItems.Count > 0 && (Content != null) && !Content.IsReadOnly && !ReadOnly;
232      moveUpButton.Enabled = itemsListView.SelectedItems.Count == 1 &&
233                             itemsListView.SelectedIndices[0] != 0 &&
234                             (Content != null) && !Content.IsReadOnly && !ReadOnly;
235      moveDownButton.Enabled = itemsListView.SelectedItems.Count == 1 &&
236                               itemsListView.SelectedIndices[0] != itemsListView.Items.Count - 1 &&
237                               (Content != null) && !Content.IsReadOnly && !ReadOnly;
238      removeButton.Enabled = itemsListView.SelectedItems.Count > 0 && (Content != null) && !Content.IsReadOnly && !ReadOnly;
239      AdjustListViewColumnSizes();
240
241      if (showDetailsCheckBox.Checked) {
242        if (itemsListView.SelectedItems.Count == 1) {
243          T item = itemsListView.SelectedItems[0].Tag as T;
244          detailsGroupBox.Enabled = true;
245          viewHost.Content = item;
246        } else {
247          viewHost.Content = null;
248          detailsGroupBox.Enabled = false;
249        }
250      }
251    }
252
253    protected virtual void itemsListView_KeyDown(object sender, KeyEventArgs e) {
254      if (e.KeyCode == Keys.Delete) {
255        if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
256          foreach (ListViewItem item in itemsListView.SelectedItems)
257            Content[item.Index] = null;
258        }
259      }
260    }
261
262    protected virtual void itemsListView_DoubleClick(object sender, EventArgs e) {
263      if (itemsListView.SelectedItems.Count == 1) {
264        T item = itemsListView.SelectedItems[0].Tag as T;
265        if (item != null) {
266          IContentView view = MainFormManager.MainForm.ShowContent(item);
267          if (view != null) {
268            view.ReadOnly = ReadOnly;
269            view.Locked = Locked;
270          }
271        }
272      }
273    }
274
275    protected virtual void itemsListView_ItemDrag(object sender, ItemDragEventArgs e) {
276      if (!Locked) {
277        List<T> items = new List<T>();
278        foreach (ListViewItem listViewItem in itemsListView.SelectedItems) {
279          T item = listViewItem.Tag as T;
280          if (item != null) items.Add(item);
281        }
282
283        if (items.Count > 0) {
284          DataObject data = new DataObject();
285          if (items.Count == 1) data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items[0]);
286          else data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items);
287          if (Content.IsReadOnly || ReadOnly) {
288            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
289          } else {
290            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
291            if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
292              foreach (ListViewItem listViewItem in itemsListView.SelectedItems.Cast<ListViewItem>().ToArray())
293                Content[listViewItem.Index] = null;
294            }
295          }
296        }
297      }
298    }
299    protected virtual void itemsListView_DragEnter(object sender, DragEventArgs e) {
300      validDragOperation = !Content.IsReadOnly && !ReadOnly && e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is T;
301    }
302    protected virtual void itemsListView_DragOver(object sender, DragEventArgs e) {
303      e.Effect = DragDropEffects.None;
304      if (validDragOperation) {
305        Point p = itemsListView.PointToClient(new Point(e.X, e.Y));
306        ListViewItem listViewItem = itemsListView.GetItemAt(p.X, p.Y);
307        if (listViewItem != null) {
308          if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
309          else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
310          else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
311          else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
312          else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
313        }
314      }
315    }
316    protected virtual void itemsListView_DragDrop(object sender, DragEventArgs e) {
317      if (e.Effect != DragDropEffects.None) {
318        Point p = itemsListView.PointToClient(new Point(e.X, e.Y));
319        ListViewItem listViewItem = itemsListView.GetItemAt(p.X, p.Y);
320        T item = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as T;
321        Content[listViewItem.Index] = e.Effect.HasFlag(DragDropEffects.Copy) ? (T)item.Clone() : item;
322      }
323    }
324    #endregion
325
326    #region Button Events
327    protected virtual void addButton_Click(object sender, EventArgs e) {
328      if (itemsListView.SelectedItems.Count > 0) {
329        T item = CreateItem();
330        if (item != null) {
331          foreach (ListViewItem listViewItem in itemsListView.SelectedItems)
332            Content[listViewItem.Index] = item;
333        }
334      }
335    }
336    protected virtual void moveUpButton_Click(object sender, EventArgs e) {
337      if (itemsListView.SelectedItems.Count == 1) {
338        int index = itemsListView.SelectedIndices[0];
339        Content.Reverse(index - 1, 2);
340        itemsListView.Items[index].Selected = false;
341        itemsListView.Items[index - 1].Selected = true;
342      }
343    }
344    protected virtual void moveDownButton_Click(object sender, EventArgs e) {
345      if (itemsListView.SelectedItems.Count == 1) {
346        int index = itemsListView.SelectedIndices[0];
347        Content.Reverse(index, 2);
348        itemsListView.Items[index].Selected = false;
349        itemsListView.Items[index + 1].Selected = true;
350      }
351    }
352    protected virtual void removeButton_Click(object sender, EventArgs e) {
353      if (itemsListView.SelectedItems.Count > 0) {
354        foreach (ListViewItem item in itemsListView.SelectedItems)
355          Content[item.Index] = null;
356      }
357    }
358    #endregion
359
360    #region CheckBox Events
361    protected virtual void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
362      if (showDetailsCheckBox.Checked) {
363        splitContainer.Panel2Collapsed = false;
364        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
365        viewHost.Content = itemsListView.SelectedItems.Count == 1 ? (T)itemsListView.SelectedItems[0].Tag : null;
366      } else {
367        splitContainer.Panel2Collapsed = true;
368        viewHost.Content = null;
369      }
370    }
371    #endregion
372
373    #region Content Events
374    protected virtual void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
375      if (InvokeRequired)
376        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsReplaced), sender, e);
377      else {
378        int[] selected = new int[itemsListView.SelectedIndices.Count];
379        itemsListView.SelectedIndices.CopyTo(selected, 0);
380
381        List<ListViewItem> listViewItems = new List<ListViewItem>();
382        foreach (IndexedItem<T> item in e.OldItems)
383          listViewItems.Add(itemsListView.Items[item.Index]);
384        foreach (ListViewItem listViewItem in listViewItems)
385          RemoveListViewItem(listViewItem);
386        RebuildImageList();
387
388        foreach (IndexedItem<T> item in e.Items)
389          InsertListViewItem(item.Index, CreateListViewItem(item.Value));
390        AdjustListViewColumnSizes();
391
392        for (int i = 0; i < selected.Length; i++)
393          itemsListView.Items[selected[i]].Selected = true;
394      }
395    }
396    protected virtual void Content_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
397      if (InvokeRequired)
398        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_ItemsMoved), sender, e);
399      else {
400        foreach (IndexedItem<T> item in e.Items) {
401          ListViewItem listViewItem = itemsListView.Items[item.Index];
402          listViewItem.Tag = item.Value;
403          UpdateListViewItemImage(listViewItem);
404          UpdateListViewItemText(listViewItem);
405        }
406      }
407    }
408    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
409      if (InvokeRequired)
410        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<T>>(Content_CollectionReset), sender, e);
411      else {
412        List<ListViewItem> listViewItems = new List<ListViewItem>();
413        foreach (IndexedItem<T> item in e.OldItems)
414          listViewItems.Add(itemsListView.Items[item.Index]);
415        foreach (ListViewItem listViewItem in listViewItems)
416          RemoveListViewItem(listViewItem);
417        RebuildImageList();
418
419        foreach (IndexedItem<T> item in e.Items)
420          InsertListViewItem(item.Index, CreateListViewItem(item.Value));
421        AdjustListViewColumnSizes();
422      }
423    }
424    #endregion
425
426    #region Item Events
427    protected virtual void Item_ItemImageChanged(object sender, EventArgs e) {
428      if (InvokeRequired)
429        Invoke(new EventHandler(Item_ItemImageChanged), sender, e);
430      else {
431        T item = (T)sender;
432        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
433          UpdateListViewItemImage(listViewItem);
434      }
435    }
436    protected virtual void Item_ToStringChanged(object sender, EventArgs e) {
437      if (InvokeRequired)
438        Invoke(new EventHandler(Item_ToStringChanged), sender, e);
439      else {
440        T item = (T)sender;
441        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
442          UpdateListViewItemText(listViewItem);
443      }
444    }
445    #endregion
446
447    #region Helpers
448    protected virtual void AdjustListViewColumnSizes() {
449      if (itemsListView.Items.Count > 0) {
450        for (int i = 0; i < itemsListView.Columns.Count; i++)
451          itemsListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
452      }
453    }
454    protected virtual void RebuildImageList() {
455      itemsListView.SmallImageList.Images.Clear();
456      foreach (ListViewItem listViewItem in itemsListView.Items) {
457        T item = listViewItem.Tag as T;
458        itemsListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
459        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
460      }
461    }
462    #endregion
463  }
464}
Note: See TracBrowser for help on using the repository browser.