Free cookie consent management tool by TermsFeed Policy Generator

source: branches/NewItemDialog/HeuristicLab.Optimizer/3.3/NewItemDialog.cs @ 12202

Last change on this file since 12202 was 12202, checked in by pfleck, 9 years ago

#2025 Changed tab indices and focus behavior on first show.

File size: 9.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Linq;
25using System.Windows.Forms;
26using HeuristicLab.Core;
27using HeuristicLab.PluginInfrastructure;
28
29namespace HeuristicLab.Optimizer {
30  internal partial class NewItemDialog : Form {
31    private bool isInitialized;
32    private bool firstShown = true;
33
34    private List<TreeNode> treeNodes;
35    private string currentSearchString;
36
37    private Type selectedType;
38    public Type SelectedType {
39      get { return selectedType; }
40      private set {
41        if (value != selectedType) {
42          selectedType = value;
43          OnSelectedTypeChanged();
44        }
45      }
46    }
47
48    private IItem item;
49    public IItem Item {
50      get { return item; }
51    }
52
53    public NewItemDialog() {
54      InitializeComponent();
55      treeNodes = new List<TreeNode>();
56      currentSearchString = string.Empty;
57      item = null;
58      SelectedTypeChanged += this_SelectedTypeChanged;
59    }
60
61    private void NewItemDialog_Load(object sender, EventArgs e) {
62      if (isInitialized) return;
63
64      var categories =
65        from t in ApplicationManager.Manager.GetTypes(typeof(IItem))
66        where CreatableAttribute.IsCreatable(t)
67        orderby CreatableAttribute.GetCategory(t), ItemAttribute.GetName(t), ItemAttribute.GetVersion(t) ascending
68        group t by CreatableAttribute.GetCategory(t) into c
69        select c;
70
71      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class);      // default icon
72      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Namespace);  // plugins
73      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Interface);  // interfacesitemsListView.SmallImageList = new ImageList();
74      imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Template);   // generic types
75
76      foreach (var category in categories) {
77        var categoryNode = new TreeNode(category.Key) {
78          ImageIndex = 1,
79          Tag = category.Key,
80        };
81        categoryNode.SelectedImageIndex = categoryNode.ImageIndex;
82
83        foreach (var creatable in category) {
84          string name = ItemAttribute.GetName(creatable);
85          string version = ItemAttribute.GetVersion(creatable).ToString();
86          string description = ItemAttribute.GetDescription(creatable);
87
88          var itemNode = new TreeNode(name) {
89            ImageIndex = 0,
90            Tag = creatable
91          };
92          itemNode.SelectedImageIndex = itemNode.ImageIndex;
93          categoryNode.Nodes.Add(itemNode);
94
95          /*
96          ListViewItem item = new ListViewItem(new string[] { name, version, description }, group);
97          item.ImageIndex = 0;
98          Image image = ItemAttribute.GetImage(creatable);
99          if (image != null) {
100            itemsListView.SmallImageList.Images.Add(image);
101            item.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
102          }
103          item.Tag = creatable;
104          itemsListView.Items.Add(item);*/
105        }
106        if (categoryNode.Nodes.Count > 0)
107          treeNodes.Add(categoryNode);
108      }
109      foreach (var node in treeNodes)
110        typesTreeView.Nodes.Add((TreeNode)node.Clone());
111      isInitialized = true;
112    }
113    private void NewItemDialog_Shown(object sender, EventArgs e) {
114      SelectedType = null;
115      if (firstShown) {
116        searchTextBox.Focus();
117        firstShown = false;
118      }
119    }
120
121    public virtual void Filter(string searchString) {
122      if (InvokeRequired) {
123        Invoke(new Action<string>(Filter), searchString);
124      } else {
125        searchString = searchString.ToLower();
126
127        if (!searchString.Contains(currentSearchString)) {
128          typesTreeView.BeginUpdate();
129          // expand saerch -> restore all tree nodes
130          var selectedNode = typesTreeView.SelectedNode;
131          typesTreeView.Nodes.Clear();
132          foreach (TreeNode node in treeNodes)
133            typesTreeView.Nodes.Add((TreeNode)node.Clone());
134          RestoreSelectedNode(selectedNode);
135          typesTreeView.EndUpdate();
136        }
137
138        // remove nodes
139        typesTreeView.BeginUpdate();
140        int i = 0;
141        var searchTokens = searchString.Split(' ');
142        while (i < typesTreeView.Nodes.Count) {
143          int j = 0;
144          while (j < typesTreeView.Nodes[i].Nodes.Count) {
145            if (searchTokens.Any(searchToken => !typesTreeView.Nodes[i].Nodes[j].Text.ToLower().Contains(searchToken))) {
146              if ((typesTreeView.Nodes[i].Nodes[j].Tag as Type).Equals(SelectedType))
147                SelectedType = null;
148              typesTreeView.Nodes[i].Nodes[j].Remove();
149            } else
150              j++;
151          }
152          if (typesTreeView.Nodes[i].Nodes.Count == 0)
153            typesTreeView.Nodes[i].Remove();
154          else
155            i++;
156        }
157        typesTreeView.EndUpdate();
158        currentSearchString = searchString;
159
160        // if there is just one type node left, select by default
161        if (typesTreeView.Nodes.Count == 1) {
162          if (typesTreeView.Nodes[0].Nodes.Count == 1) {
163            typesTreeView.SelectedNode = typesTreeView.Nodes[0].Nodes[0];
164          }
165        }
166
167        if (typesTreeView.Nodes.Count == 0) {
168          SelectedType = null;
169          typesTreeView.Enabled = false;
170        } else {
171          SetTreeNodeVisibility();
172          typesTreeView.Enabled = true;
173        }
174        UpdateDescription();
175      }
176    }
177
178    protected virtual void UpdateDescription() {
179      descriptionTextBox.Text = string.Empty;
180
181      if (typesTreeView.SelectedNode != null) {
182        string category = typesTreeView.SelectedNode.Tag as string;
183        if (category != null) {
184          descriptionTextBox.Text = category;
185        }
186        Type type = typesTreeView.SelectedNode.Tag as Type;
187        if (type != null) {
188          string description = ItemAttribute.GetDescription(type);
189          if (description != null)
190            descriptionTextBox.Text = description;
191        }
192      } else if (typesTreeView.Nodes.Count == 0) {
193        descriptionTextBox.Text = "No types found";
194      }
195    }
196
197    #region Events
198    public event EventHandler SelectedTypeChanged;
199    protected virtual void OnSelectedTypeChanged() {
200      if (SelectedTypeChanged != null)
201        SelectedTypeChanged(this, EventArgs.Empty);
202    }
203    #endregion
204
205    #region Control Events
206    protected virtual void searchTextBox_TextChanged(object sender, EventArgs e) {
207      Filter(searchTextBox.Text);
208    }
209
210    protected virtual void itemsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
211      if (typesTreeView.SelectedNode == null) SelectedType = null;
212      else SelectedType = typesTreeView.SelectedNode.Tag as Type;
213      UpdateDescription();
214    }
215
216    protected virtual void itemsTreeView_VisibleChanged(object sender, EventArgs e) {
217      if (Visible) SetTreeNodeVisibility();
218    }
219    #endregion
220
221    #region Helpers
222    private void RestoreSelectedNode(TreeNode selectedNode) {
223      if (selectedNode != null) {
224        foreach (TreeNode node in typesTreeView.Nodes) {
225          if (node.Text.Equals(selectedNode.Text)) typesTreeView.SelectedNode = node;
226          foreach (TreeNode child in node.Nodes) {
227            if ((child.Text.Equals(selectedNode.Text)) && (child.Tag == selectedNode.Tag))
228              typesTreeView.SelectedNode = child;
229          }
230        }
231        if (typesTreeView.SelectedNode == null) SelectedType = null;
232      }
233    }
234    private void SetTreeNodeVisibility() {
235      typesTreeView.ExpandAll();
236      TreeNode selectedNode = typesTreeView.SelectedNode;
237      if (selectedNode != null) {
238        typesTreeView.SelectedNode = selectedNode;
239        selectedNode.EnsureVisible();
240      } else if (string.IsNullOrEmpty(currentSearchString) && typesTreeView.Nodes.Count > 1) {
241        typesTreeView.Nodes[0].EnsureVisible();
242      }
243    }
244    #endregion
245
246    private void okButton_Click(object sender, EventArgs e) {
247      if (SelectedType != null) {
248        item = (IItem)Activator.CreateInstance(SelectedType);
249        DialogResult = DialogResult.OK;
250        Close();
251      }
252    }
253    private void itemTreeView_DoubleClick(object sender, EventArgs e) {
254      if (SelectedType != null) {
255        item = (IItem)Activator.CreateInstance(SelectedType);
256        DialogResult = DialogResult.OK;
257        Close();
258      }
259    }
260    private void this_SelectedTypeChanged(object sender, EventArgs e) {
261      okButton.Enabled = SelectedType != null;
262    }
263
264    private void expandAllButton_Click(object sender, EventArgs e) {
265      typesTreeView.ExpandAll();
266    }
267    private void collapseAllButton_Click(object sender, EventArgs e) {
268      typesTreeView.CollapseAll();
269    }
270  }
271}
Note: See TracBrowser for help on using the repository browser.