Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionView.cs @ 5302

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

Fixed exception which was thrown when item updates are still pending after the content of an ItemCollectionView has already been changed (#1324)

File size: 18.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Core;
29using HeuristicLab.Core.Views;
30using HeuristicLab.MainForm;
31using HeuristicLab.MainForm.WindowsForms;
32
33namespace HeuristicLab.Optimization.Views {
34  [View("RunCollection View")]
35  [Content(typeof(RunCollection), true)]
36  [Content(typeof(IItemCollection<IRun>), false)]
37  public sealed partial class RunCollectionView : ItemView {
38    private Dictionary<IRun, List<ListViewItem>> itemListViewItemMapping;
39
40    public new IItemCollection<IRun> Content {
41      get { return (IItemCollection<IRun>)base.Content; }
42      set { base.Content = value; }
43    }
44
45    public RunCollection RunCollection {
46      get { return Content as RunCollection; }
47    }
48
49    public ListView ItemsListView {
50      get { return itemsListView; }
51    }
52
53    public RunCollectionView() {
54      InitializeComponent();
55      itemsGroupBox.Text = "Runs";
56      itemListViewItemMapping = new Dictionary<IRun, List<ListViewItem>>();
57    }
58
59    protected override void DeregisterContentEvents() {
60      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
61      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
62      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
63      foreach (IRun run in itemListViewItemMapping.Keys) {
64        DeregisterItemEvents(run);
65      }
66      base.DeregisterContentEvents();
67    }
68    protected override void RegisterContentEvents() {
69      base.RegisterContentEvents();
70      Content.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
71      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
72      Content.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
73    }
74    private void DeregisterItemEvents(IRun item) {
75      item.ItemImageChanged -= new EventHandler(Item_ItemImageChanged);
76      item.ToStringChanged -= new EventHandler(Item_ToStringChanged);
77      item.Changed -= new EventHandler(Item_Changed);
78    }
79    private void RegisterItemEvents(IRun item) {
80      item.ItemImageChanged += new EventHandler(Item_ItemImageChanged);
81      item.ToStringChanged += new EventHandler(Item_ToStringChanged);
82      item.Changed += new EventHandler(Item_Changed);
83    }
84
85    protected override void OnInitialized(EventArgs e) {
86      base.OnInitialized(e);
87      var viewTypes = MainFormManager.GetViewTypes(typeof(RunCollection), true);
88      foreach (Type viewType in viewTypes.OrderBy(x => ViewAttribute.GetViewName(x))) {
89        if ((viewType != typeof(ItemCollectionView<IRun>)) && (viewType != typeof(ViewHost))) {
90          ToolStripMenuItem menuItem = new ToolStripMenuItem();
91          menuItem.Text = ViewAttribute.GetViewName(viewType);
92          menuItem.Tag = viewType;
93          menuItem.Click += new EventHandler(menuItem_Click);
94          analyzeRunsToolStripDropDownButton.DropDownItems.Add(menuItem);
95        }
96      }
97    }
98
99    protected override void OnContentChanged() {
100      base.OnContentChanged();
101
102      string selectedName = null;
103      if ((itemsListView.SelectedItems.Count == 1) && (itemsListView.SelectedItems[0].Tag != null))
104        selectedName = ((IRun)itemsListView.SelectedItems[0].Tag).Name;
105
106      itemsListView.Items.Clear();
107      itemListViewItemMapping.Clear();
108      RebuildImageList();
109      viewHost.Content = null;
110
111      if (Content != null) {
112        if (RunCollection != null) {
113          if (!tabControl.TabPages.Contains(constraintPage))
114            tabControl.TabPages.Add(constraintPage);
115          runCollectionConstraintCollectionView.Content = RunCollection.Constraints;
116          runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
117        }
118        foreach (IRun item in Content) {
119          ListViewItem listViewItem = CreateListViewItem(item);
120          AddListViewItem(listViewItem);
121          if ((selectedName != null) && item.Name.Equals(selectedName))
122            listViewItem.Selected = true;
123        }
124        AdjustListViewColumnSizes();
125      } else {
126        runCollectionConstraintCollectionView.Content = null;
127        if (tabControl.TabPages.Contains(constraintPage))
128          tabControl.TabPages.Remove(constraintPage);
129      }
130    }
131
132    protected override void SetEnabledStateOfControls() {
133      base.SetEnabledStateOfControls();
134      if (Content == null) {
135        analyzeRunsToolStripDropDownButton.Enabled = false;
136        runCollectionConstraintCollectionView.ReadOnly = true;
137        itemsListView.Enabled = false;
138        detailsGroupBox.Enabled = false;
139        viewHost.Enabled = false;
140        removeButton.Enabled = false;
141        clearButton.Enabled = false;
142      } else {
143        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
144        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
145        itemsListView.Enabled = true;
146        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
147        removeButton.Enabled = itemsListView.SelectedItems.Count > 0 && !Content.IsReadOnly && !ReadOnly;
148        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
149        viewHost.Enabled = true;
150      }
151    }
152
153    private ListViewItem CreateListViewItem(IRun item) {
154      ListViewItem listViewItem = new ListViewItem();
155      if (item == null) {
156        listViewItem.Text = "null";
157        itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
158        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
159      } else {
160        listViewItem.Text = item.ToString();
161        listViewItem.ToolTipText = item.ItemName + ": " + item.ItemDescription;
162        itemsListView.SmallImageList.Images.Add(item.ItemImage);
163        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
164        listViewItem.Tag = item;
165
166        if (item.Visible) {
167          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
168          listViewItem.ForeColor = item.Color;
169        } else {
170          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
171          listViewItem.ForeColor = Color.LightGray;
172        }
173      }
174      return listViewItem;
175    }
176    private void AddListViewItem(ListViewItem listViewItem) {
177      itemsListView.Items.Add(listViewItem);
178      IRun run = listViewItem.Tag as IRun;
179      if (run != null) {
180        if (!itemListViewItemMapping.ContainsKey(run)) {
181          itemListViewItemMapping.Add(run, new List<ListViewItem>());
182          RegisterItemEvents(run);
183        }
184        itemListViewItemMapping[run].Add(listViewItem);
185      }
186    }
187    private void RemoveListViewItem(ListViewItem listViewItem) {
188      IRun run = listViewItem.Tag as IRun;
189      if (run != null) {
190        itemListViewItemMapping[run].Remove(listViewItem);
191        if (itemListViewItemMapping[run].Count == 0) {
192          DeregisterItemEvents(run);
193          itemListViewItemMapping.Remove(run);
194        }
195      }
196      listViewItem.Remove();
197    }
198    private void UpdateListViewItemImage(ListViewItem listViewItem) {
199      IRun item = listViewItem.Tag as IRun;
200      int i = listViewItem.ImageIndex;
201      listViewItem.ImageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
202      listViewItem.ImageIndex = -1;
203      listViewItem.ImageIndex = i;
204    }
205    private void UpdateListViewItemText(ListViewItem listViewItem) {
206      IRun item = listViewItem.Tag as IRun;
207      listViewItem.Text = item == null ? "null" : item.ToString();
208      listViewItem.ToolTipText = item == null ? string.Empty : item.ItemName + ": " + item.ItemDescription;
209    }
210    private IEnumerable<ListViewItem> GetListViewItemsForItem(IRun item) {
211      if (item == null) {
212        List<ListViewItem> listViewItems = new List<ListViewItem>();
213        foreach (ListViewItem listViewItem in itemsListView.Items) {
214          if (listViewItem.Tag == null) listViewItems.Add(listViewItem);
215        }
216        return listViewItems;
217      } else {
218        List<ListViewItem> listViewItems = null;
219        itemListViewItemMapping.TryGetValue(item, out listViewItems);
220        return listViewItems == null ? Enumerable.Empty<ListViewItem>() : listViewItems;
221      }
222    }
223
224    #region ListView Events
225    private void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
226      removeButton.Enabled = itemsListView.SelectedItems.Count > 0 && (Content != null) && !Content.IsReadOnly && !ReadOnly;
227      AdjustListViewColumnSizes();
228      if (showDetailsCheckBox.Checked) {
229        if (itemsListView.SelectedItems.Count == 1) {
230          IRun item = (IRun)itemsListView.SelectedItems[0].Tag;
231          detailsGroupBox.Enabled = true;
232          viewHost.Content = item;
233        } else {
234          viewHost.Content = null;
235          detailsGroupBox.Enabled = false;
236        }
237      }
238    }
239    private void itemsListView_KeyDown(object sender, KeyEventArgs e) {
240      if (e.KeyCode == Keys.Delete) {
241        if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
242          foreach (ListViewItem item in itemsListView.SelectedItems)
243            Content.Remove((IRun)item.Tag);
244        }
245      }
246    }
247    private void itemsListView_DoubleClick(object sender, EventArgs e) {
248      if (itemsListView.SelectedItems.Count == 1) {
249        IRun item = itemsListView.SelectedItems[0].Tag as IRun;
250        if (item != null) {
251          IContentView view = MainFormManager.MainForm.ShowContent(item);
252          if (view != null) {
253            view.ReadOnly = ReadOnly;
254            view.Locked = Locked;
255          }
256        }
257      }
258    }
259    private void itemsListView_ItemDrag(object sender, ItemDragEventArgs e) {
260      if (!Locked) {
261        ListViewItem listViewItem = (ListViewItem)e.Item;
262        IRun item = listViewItem.Tag as IRun;
263        if (item != null) {
264          DataObject data = new DataObject();
265          data.SetData("Type", item.GetType());
266          data.SetData("Value", item);
267          if (Content.IsReadOnly || ReadOnly) {
268            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
269          } else {
270            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
271            if ((result & DragDropEffects.Move) == DragDropEffects.Move)
272              Content.Remove(item);
273          }
274        }
275      }
276    }
277    private void itemsListView_DragEnterOver(object sender, DragEventArgs e) {
278      e.Effect = DragDropEffects.None;
279      Type type = e.Data.GetData("Type") as Type;
280      if (!Content.IsReadOnly && !ReadOnly && (type != null) && (typeof(IRun).IsAssignableFrom(type))) {
281        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
282        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
283        else if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) e.Effect = DragDropEffects.Copy;
284        else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) e.Effect = DragDropEffects.Move;
285        else if ((e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) e.Effect = DragDropEffects.Link;
286      }
287    }
288    private void itemsListView_DragDrop(object sender, DragEventArgs e) {
289      if (e.Effect != DragDropEffects.None) {
290        IRun item = e.Data.GetData("Value") as IRun;
291        if ((e.Effect & DragDropEffects.Copy) == DragDropEffects.Copy) item = (IRun)item.Clone();
292        Content.Add(item);
293      }
294    }
295    #endregion
296
297    #region Button Events
298    private void menuItem_Click(object sender, EventArgs e) {
299      ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
300      Type viewType = (Type)menuItem.Tag;
301      IContentView view = MainFormManager.MainForm.ShowContent(Content, viewType);
302      if (view != null) {
303        view.Locked = Locked;
304        view.ReadOnly = ReadOnly;
305      }
306    }
307    private void removeButton_Click(object sender, EventArgs e) {
308      if (itemsListView.SelectedItems.Count > 0) {
309        foreach (ListViewItem item in itemsListView.SelectedItems)
310          Content.Remove((IRun)item.Tag);
311        itemsListView.SelectedItems.Clear();
312      }
313    }
314    private void clearButton_Click(object sender, EventArgs e) {
315      Content.Clear();
316    }
317    #endregion
318
319    #region CheckBox Events
320    private void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
321      if (showDetailsCheckBox.Checked) {
322        splitContainer.Panel2Collapsed = false;
323        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
324        viewHost.Content = itemsListView.SelectedItems.Count == 1 ? (IRun)itemsListView.SelectedItems[0].Tag : null;
325      } else {
326        splitContainer.Panel2Collapsed = true;
327        viewHost.Content = null;
328      }
329    }
330    #endregion
331
332    #region Content Events
333    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
334      if (InvokeRequired)
335        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
336      else {
337        foreach (IRun item in e.Items)
338          AddListViewItem(CreateListViewItem(item));
339
340        AdjustListViewColumnSizes();
341        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
342        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
343        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
344      }
345    }
346    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
347      if (InvokeRequired)
348        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
349      else {
350        foreach (IRun item in e.Items) {
351          //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
352          ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
353          if (listViewItem != null) RemoveListViewItem(listViewItem);
354        }
355        RebuildImageList();
356        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
357        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
358        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
359      }
360    }
361    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
362      if (InvokeRequired)
363        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
364      else {
365        foreach (IRun item in e.OldItems) {
366          //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
367          ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
368          if (listViewItem != null) RemoveListViewItem(listViewItem);
369        }
370        RebuildImageList();
371        foreach (IRun item in e.Items)
372          AddListViewItem(CreateListViewItem(item));
373
374        AdjustListViewColumnSizes();
375        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
376        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
377        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
378      }
379    }
380    #endregion
381
382    #region Item Events
383    private void Item_ItemImageChanged(object sender, EventArgs e) {
384      if (InvokeRequired)
385        Invoke(new EventHandler(Item_ItemImageChanged), sender, e);
386      else {
387        IRun item = (IRun)sender;
388        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
389          UpdateListViewItemImage(listViewItem);
390      }
391    }
392    private void Item_ToStringChanged(object sender, EventArgs e) {
393      if (InvokeRequired)
394        Invoke(new EventHandler(Item_ToStringChanged), sender, e);
395      else {
396        IRun item = (IRun)sender;
397        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
398          UpdateListViewItemText(listViewItem);
399        AdjustListViewColumnSizes();
400      }
401    }
402    private void Item_Changed(object sender, EventArgs e) {
403      if (InvokeRequired)
404        this.Invoke(new EventHandler(Item_Changed), sender, e);
405      else {
406        IRun run = (IRun)sender;
407        UpdateRun(run);
408      }
409    }
410
411    private void UpdateRun(IRun run) {
412      foreach (ListViewItem listViewItem in GetListViewItemsForItem(run)) {
413        if (run.Visible) {
414          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
415          listViewItem.ForeColor = run.Color;
416        } else {
417          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
418          listViewItem.ForeColor = Color.LightGray;
419        }
420      }
421    }
422    #endregion
423
424    #region Helpers
425    private void AdjustListViewColumnSizes() {
426      if (itemsListView.Items.Count > 0) {
427        for (int i = 0; i < itemsListView.Columns.Count; i++) {
428          itemsListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
429        }
430      }
431    }
432    private void RebuildImageList() {
433      itemsListView.SmallImageList.Images.Clear();
434      foreach (ListViewItem listViewItem in itemsListView.Items) {
435        IRun item = listViewItem.Tag as IRun;
436        itemsListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
437        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
438      }
439    }
440    #endregion
441  }
442}
Note: See TracBrowser for help on using the repository browser.