Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Core.Views/3.3/ItemListView.cs @ 5445

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

Updated year of copyrights (#1406)

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