- Timestamp:
- 04/13/15 16:58:58 (10 years ago)
- Location:
- trunk/sources/HeuristicLab.Optimizer
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Optimizer
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
/branches/HLScript/HeuristicLab.Optimizer merged eligible /branches/NewItemDialog/HeuristicLab.Optimizer merged eligible /stable/HeuristicLab.Optimizer merged eligible /branches/1721-RandomForestPersistence/HeuristicLab.Optimizer 10321-10322 /branches/Algorithms.GradientDescent/HeuristicLab.Optimizer 5516-5520 /branches/Benchmarking/sources/HeuristicLab.Optimizer 6917-7005 /branches/CloningRefactoring/HeuristicLab.Optimizer 4656-4721 /branches/CodeEditor/HeuristicLab.Optimizer 11700-11806 /branches/DataAnalysis Refactoring/HeuristicLab.Optimizer 5471-5808 /branches/DataAnalysis SolutionEnsembles/HeuristicLab.Optimizer 5815-6180 /branches/DataAnalysis/HeuristicLab.Optimizer 4458-4459,4462,4464 /branches/DataPreprocessing/HeuristicLab.Optimizer 10085-11101 /branches/GP.Grammar.Editor/HeuristicLab.Optimizer 6284-6795 /branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Optimizer 5060 /branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Optimizer 6123-9799 /branches/LogResidualEvaluator/HeuristicLab.Optimizer 10202-10483 /branches/NET40/sources/HeuristicLab.Optimizer 5138-5162 /branches/NSGA-II Changes/HeuristicLab.Optimizer 12033-12122 /branches/ParallelEngine/HeuristicLab.Optimizer 5175-5192 /branches/ProblemInstancesRegressionAndClassification/HeuristicLab.Optimizer 7568-7810 /branches/QAPAlgorithms/HeuristicLab.Optimizer 6350-6627 /branches/Restructure trunk solution/HeuristicLab.Optimizer 6828 /branches/RuntimeOptimizer/HeuristicLab.Optimizer 8943-9078 /branches/ScatterSearch (trunk integration)/HeuristicLab.Optimizer 7787-8333 /branches/SlaveShutdown/HeuristicLab.Optimizer 8944-8956 /branches/SpectralKernelForGaussianProcesses/HeuristicLab.Optimizer 10204-10479 /branches/SuccessProgressAnalysis/HeuristicLab.Optimizer 5370-5682 /branches/Trunk/HeuristicLab.Optimizer 6829-6865 /branches/UnloadJobs/HeuristicLab.Optimizer 9168-9215 /branches/VNS/HeuristicLab.Optimizer 5594-5752 /branches/histogram/HeuristicLab.Optimizer 5959-6341
-
Property
svn:mergeinfo
set to
(toggle deleted branches)
-
trunk/sources/HeuristicLab.Optimizer/3.3/NewItemDialog.cs
r12012 r12305 21 21 22 22 using System; 23 using System.Collections; 24 using System.Collections.Generic; 23 25 using System.Drawing; 24 26 using System.Linq; … … 29 31 namespace HeuristicLab.Optimizer { 30 32 internal partial class NewItemDialog : Form { 31 private bool initialized; 33 private bool isInitialized; 34 35 private readonly List<TreeNode> treeNodes; 36 private string currentSearchString; 37 38 private Type selectedType; 39 public Type SelectedType { 40 get { return selectedType; } 41 private set { 42 if (value != selectedType) { 43 selectedType = value; 44 OnSelectedTypeChanged(); 45 } 46 } 47 } 32 48 33 49 private IItem item; … … 37 53 38 54 public NewItemDialog() { 39 initialized = false; 55 InitializeComponent(); 56 treeNodes = new List<TreeNode>(); 57 currentSearchString = string.Empty; 40 58 item = null; 41 InitializeComponent();59 SelectedTypeChanged += this_SelectedTypeChanged; 42 60 } 43 61 44 62 private void NewItemDialog_Load(object sender, EventArgs e) { 45 if (!initialized) { 46 var categories = from t in ApplicationManager.Manager.GetTypes(typeof(IItem)) 47 where CreatableAttribute.IsCreatable(t) 48 orderby CreatableAttribute.GetCategory(t), ItemAttribute.GetName(t), ItemAttribute.GetVersion(t) ascending 49 group t by CreatableAttribute.GetCategory(t) into c 50 select c; 51 52 itemsListView.SmallImageList = new ImageList(); 53 itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class); // default icon 54 foreach (var category in categories) { 55 ListViewGroup group = new ListViewGroup(category.Key); 56 itemsListView.Groups.Add(group); 57 foreach (var creatable in category) { 58 string name = ItemAttribute.GetName(creatable); 59 string version = ItemAttribute.GetVersion(creatable).ToString(); 60 string description = ItemAttribute.GetDescription(creatable); 61 ListViewItem item = new ListViewItem(new string[] { name, version, description }, group); 62 item.ImageIndex = 0; 63 Image image = ItemAttribute.GetImage(creatable); 64 if (image != null) { 65 itemsListView.SmallImageList.Images.Add(image); 66 item.ImageIndex = itemsListView.SmallImageList.Images.Count - 1; 67 } 68 item.Tag = creatable; 69 itemsListView.Items.Add(item); 63 if (isInitialized) return; 64 65 var categories = 66 from type in ApplicationManager.Manager.GetTypes(typeof(IItem)) 67 let category = CreatableAttribute.GetCategory(type) 68 let name = ItemAttribute.GetName(type) 69 let priority = CreatableAttribute.GetPriority(type) 70 let version = ItemAttribute.GetVersion(type) 71 where CreatableAttribute.IsCreatable(type) 72 orderby category, priority, name, version ascending 73 group type by category into categoryGroup 74 select categoryGroup; 75 76 var rootNode = CreateCategoryTree(categories); 77 CreateItemNodes(rootNode, categories); 78 79 foreach (TreeNode topNode in rootNode.Nodes) 80 treeNodes.Add(topNode); 81 foreach (var node in treeNodes) 82 typesTreeView.Nodes.Add((TreeNode)node.Clone()); 83 84 typesTreeView.TreeViewNodeSorter = new ItemTreeNodeComparer(); 85 typesTreeView.Sort(); 86 87 isInitialized = true; 88 } 89 90 private TreeNode CreateCategoryTree(IEnumerable<IGrouping<string, Type>> categories) { 91 imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class); // default icon 92 imageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Namespace); // plugins 93 94 var rootNode = new TreeNode(); 95 96 foreach (var category in categories) { 97 var fullName = category.Key; 98 var tokens = fullName.Split('#'); 99 var name = tokens.Last(); 100 var parents = tokens.Take(tokens.Length - 1); 101 102 var categoryNode = new TreeNode(name, imageIndex: 1, selectedImageIndex: 1) { 103 Name = fullName, 104 Tag = fullName 105 }; 106 107 var parentNode = FindOrCreateParentNode(rootNode, parents); 108 if (parentNode != null) 109 parentNode.Nodes.Add(categoryNode); 110 else 111 rootNode.Nodes.Add(categoryNode); 112 } 113 114 return rootNode; 115 } 116 private TreeNode FindOrCreateParentNode(TreeNode node, IEnumerable<string> parentCategories) { 117 TreeNode parentNode = null; 118 string fullName = null; 119 foreach (string parentCategory in parentCategories) { 120 fullName = fullName == null ? parentCategory : fullName + "#" + parentCategory; 121 parentNode = node.Nodes.Find(fullName, searchAllChildren: false).SingleOrDefault(); 122 if (parentNode == null) { 123 parentNode = new TreeNode(parentCategory, imageIndex: 1, selectedImageIndex: 1) { 124 Name = fullName, 125 Tag = fullName 126 }; 127 node.Nodes.Add(parentNode); 128 } 129 node = parentNode; 130 } 131 return parentNode; 132 } 133 private void CreateItemNodes(TreeNode node, IEnumerable<IGrouping<string, Type>> categories) { 134 foreach (var category in categories) { 135 var categoryNode = node.Nodes.Find(category.Key, searchAllChildren: true).Single(); 136 foreach (var creatable in category) { 137 var itemNode = CreateItemNode(creatable); 138 itemNode.Name = itemNode.Name + ":" + category.Key; 139 categoryNode.Nodes.Add(itemNode); 140 } 141 } 142 } 143 private TreeNode CreateItemNode(Type creatable) { 144 string name = ItemAttribute.GetName(creatable); 145 146 var itemNode = new TreeNode(name) { 147 ImageIndex = 0, 148 Tag = creatable, 149 Name = name 150 }; 151 152 var image = ItemAttribute.GetImage(creatable); 153 if (image != null) { 154 imageList.Images.Add(image); 155 itemNode.ImageIndex = imageList.Images.Count - 1; 156 } 157 itemNode.SelectedImageIndex = itemNode.ImageIndex; 158 159 return itemNode; 160 } 161 162 private void NewItemDialog_Shown(object sender, EventArgs e) { 163 searchTextBox.Text = string.Empty; 164 searchTextBox.Focus(); 165 SelectedType = null; 166 typesTreeView.SelectedNode = null; 167 typesTreeView.CollapseAll(); 168 UpdateDescription(); 169 } 170 171 public virtual void Filter(string searchString) { 172 if (InvokeRequired) { 173 Invoke(new Action<string>(Filter), searchString); 174 } else { 175 searchString = searchString.ToLower(); 176 177 if (!searchString.Contains(currentSearchString)) { 178 typesTreeView.BeginUpdate(); 179 // expand search -> restore all tree nodes 180 var selectedNode = typesTreeView.SelectedNode; 181 typesTreeView.Nodes.Clear(); 182 foreach (TreeNode node in treeNodes) 183 typesTreeView.Nodes.Add((TreeNode)node.Clone()); 184 RestoreSelectedNode(selectedNode); 185 typesTreeView.EndUpdate(); 186 } 187 188 // remove nodes 189 typesTreeView.BeginUpdate(); 190 var searchTokens = searchString.Split(' '); 191 192 int i = 0; 193 while (i < typesTreeView.Nodes.Count) { 194 var categoryNode = typesTreeView.Nodes[i]; 195 bool remove = FilterNode(categoryNode, searchTokens); 196 if (remove) 197 typesTreeView.Nodes.RemoveAt(i); 198 else i++; 199 } 200 typesTreeView.EndUpdate(); 201 currentSearchString = searchString; 202 203 // select first item 204 var firstNode = FirstVisibleNode; 205 while (firstNode != null && !(firstNode.Tag is Type)) 206 firstNode = firstNode.NextVisibleNode; 207 if (firstNode != null) 208 typesTreeView.SelectedNode = firstNode; 209 210 if (typesTreeView.Nodes.Count == 0) { 211 SelectedType = null; 212 typesTreeView.Enabled = false; 213 } else { 214 SetTreeNodeVisibility(); 215 typesTreeView.Enabled = true; 216 } 217 UpdateDescription(); 218 } 219 } 220 221 private bool FilterNode(TreeNode node, string[] searchTokens) { 222 if (node.Tag is string) { // Category node 223 int i = 0; 224 while (i < node.Nodes.Count) { 225 bool remove = FilterNode(node.Nodes[i], searchTokens); 226 if (remove) 227 node.Nodes.RemoveAt(i); 228 else i++; 229 } 230 return node.Nodes.Count == 0; 231 } if (node.Tag is Type) { // Type node 232 var text = node.Text; 233 if (searchTokens.Any(searchToken => !text.ToLower().Contains(searchToken))) { 234 var typeTag = (Type)node.Tag; 235 if (typeTag == SelectedType) { 236 SelectedType = null; 237 typesTreeView.SelectedNode = null; 70 238 } 71 } 72 for (int i = 0; i < itemsListView.Columns.Count; i++) 73 itemsListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent); 74 initialized = true; 75 } 76 } 77 78 private void NewItemDialog_Shown(object sender, EventArgs e) { 79 item = null; 80 } 81 82 private void itemTypesListView_SelectedIndexChanged(object sender, EventArgs e) { 83 okButton.Enabled = itemsListView.SelectedItems.Count == 1; 84 } 239 return true; 240 } 241 return false; 242 } 243 throw new InvalidOperationException("Encountered neither a category nor a creatable node during tree traversal."); 244 } 245 246 protected virtual void UpdateDescription() { 247 itemDescriptionTextBox.Text = string.Empty; 248 pluginDescriptionTextBox.Text = string.Empty; 249 pluginTextBox.Text = string.Empty; 250 versionTextBox.Text = string.Empty; 251 252 if (typesTreeView.SelectedNode != null) { 253 string category = typesTreeView.SelectedNode.Tag as string; 254 if (category != null) { 255 itemDescriptionTextBox.Text = category; 256 } 257 Type type = typesTreeView.SelectedNode.Tag as Type; 258 if (type != null) { 259 string description = ItemAttribute.GetDescription(type); 260 var version = ItemAttribute.GetVersion(type); 261 var plugin = ApplicationManager.Manager.GetDeclaringPlugin(type); 262 if (description != null) 263 itemDescriptionTextBox.Text = description; 264 if (plugin != null) { 265 pluginTextBox.Text = plugin.Name; 266 pluginDescriptionTextBox.Text = plugin.Description; 267 } 268 if (version != null) 269 versionTextBox.Text = version.ToString(); 270 } 271 } else if (typesTreeView.Nodes.Count == 0) { 272 itemDescriptionTextBox.Text = "No types found"; 273 } 274 } 275 276 #region Events 277 public event EventHandler SelectedTypeChanged; 278 protected virtual void OnSelectedTypeChanged() { 279 if (SelectedTypeChanged != null) 280 SelectedTypeChanged(this, EventArgs.Empty); 281 } 282 #endregion 283 284 #region Control Events 285 protected virtual void searchTextBox_TextChanged(object sender, EventArgs e) { 286 Filter(searchTextBox.Text); 287 } 288 289 protected virtual void itemsTreeView_AfterSelect(object sender, TreeViewEventArgs e) { 290 if (typesTreeView.SelectedNode == null) SelectedType = null; 291 else SelectedType = typesTreeView.SelectedNode.Tag as Type; 292 UpdateDescription(); 293 } 294 295 protected virtual void itemsTreeView_VisibleChanged(object sender, EventArgs e) { 296 if (Visible) SetTreeNodeVisibility(); 297 } 298 #endregion 299 300 #region Helpers 301 private void RestoreSelectedNode(TreeNode selectedNode) { 302 if (selectedNode != null) { 303 var node = typesTreeView.Nodes.Find(selectedNode.Name, searchAllChildren: true).SingleOrDefault(); 304 typesTreeView.SelectedNode = node; 305 if (typesTreeView.SelectedNode == null) SelectedType = null; 306 } 307 } 308 private void SetTreeNodeVisibility() { 309 TreeNode selectedNode = typesTreeView.SelectedNode; 310 if (string.IsNullOrEmpty(currentSearchString) && (typesTreeView.Nodes.Count > 1)) { 311 typesTreeView.CollapseAll(); 312 if (selectedNode != null) typesTreeView.SelectedNode = selectedNode; 313 } else { 314 typesTreeView.ExpandAll(); 315 } 316 if (selectedNode != null) selectedNode.EnsureVisible(); 317 } 318 #endregion 85 319 86 320 private void okButton_Click(object sender, EventArgs e) { 87 if ( itemsListView.SelectedItems.Count == 1) {88 item = (IItem)Activator.CreateInstance( (Type)itemsListView.SelectedItems[0].Tag);321 if (SelectedType != null) { 322 item = (IItem)Activator.CreateInstance(SelectedType); 89 323 DialogResult = DialogResult.OK; 90 324 Close(); 91 325 } 92 326 } 93 private void itemT ypesListView_DoubleClick(object sender, EventArgs e) {94 if ( itemsListView.SelectedItems.Count == 1) {95 item = (IItem)Activator.CreateInstance( (Type)itemsListView.SelectedItems[0].Tag);327 private void itemTreeView_DoubleClick(object sender, EventArgs e) { 328 if (SelectedType != null) { 329 item = (IItem)Activator.CreateInstance(SelectedType); 96 330 DialogResult = DialogResult.OK; 97 331 Close(); 98 332 } 99 333 } 334 private void this_SelectedTypeChanged(object sender, EventArgs e) { 335 okButton.Enabled = SelectedType != null; 336 } 337 338 private void expandAllButton_Click(object sender, EventArgs e) { 339 typesTreeView.ExpandAll(); 340 } 341 private void collapseAllButton_Click(object sender, EventArgs e) { 342 typesTreeView.CollapseAll(); 343 } 344 345 private TreeNode toolStripMenuNode = null; 346 private void typesTreeView_MouseDown(object sender, MouseEventArgs e) { 347 if (e.Button == MouseButtons.Right) { 348 Point coordinates = typesTreeView.PointToClient(Cursor.Position); 349 toolStripMenuNode = typesTreeView.GetNodeAt(coordinates); 350 351 if (toolStripMenuNode != null && coordinates.X >= toolStripMenuNode.Bounds.Left && 352 coordinates.X <= toolStripMenuNode.Bounds.Right) { 353 typesTreeView.SelectedNode = toolStripMenuNode; 354 355 expandToolStripMenuItem.Enabled = 356 expandToolStripMenuItem.Visible = !toolStripMenuNode.IsExpanded && toolStripMenuNode.Nodes.Count > 0; 357 collapseToolStripMenuItem.Enabled = collapseToolStripMenuItem.Visible = toolStripMenuNode.IsExpanded; 358 } else { 359 expandToolStripMenuItem.Enabled = expandToolStripMenuItem.Visible = false; 360 collapseToolStripMenuItem.Enabled = collapseToolStripMenuItem.Visible = false; 361 } 362 expandAllToolStripMenuItem.Enabled = 363 expandAllToolStripMenuItem.Visible = 364 !typesTreeView.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x)); 365 collapseAllToolStripMenuItem.Enabled = 366 collapseAllToolStripMenuItem.Visible = typesTreeView.Nodes.OfType<TreeNode>().Any(x => x.IsExpanded); 367 if (contextMenuStrip.Items.Cast<ToolStripMenuItem>().Any(item => item.Enabled)) 368 contextMenuStrip.Show(Cursor.Position); 369 } 370 } 371 private bool TreeNodeIsFullyExpanded(TreeNode node) { 372 return (node.Nodes.Count == 0) || (node.IsExpanded && node.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x))); 373 } 374 375 private void expandToolStripMenuItem_Click(object sender, EventArgs e) { 376 if (toolStripMenuNode != null) toolStripMenuNode.ExpandAll(); 377 } 378 private void expandAllToolStripMenuItem_Click(object sender, EventArgs e) { 379 typesTreeView.ExpandAll(); 380 } 381 private void collapseToolStripMenuItem_Click(object sender, EventArgs e) { 382 if (toolStripMenuNode != null) toolStripMenuNode.Collapse(); 383 } 384 private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e) { 385 typesTreeView.CollapseAll(); 386 } 387 388 private void clearSearchButton_Click(object sender, EventArgs e) { 389 searchTextBox.Text = string.Empty; 390 searchTextBox.Focus(); 391 } 392 393 private void searchTextBox_KeyDown(object sender, KeyEventArgs e) { 394 if (typesTreeView.Nodes.Count == 0) 395 return; 396 397 if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down) { 398 var selectedNode = typesTreeView.SelectedNode; 399 400 if (selectedNode == null) { // nothing selected => select first or last 401 if (e.KeyCode == Keys.Down) typesTreeView.SelectedNode = FirstVisibleNode; 402 if (e.KeyCode == Keys.Up) typesTreeView.SelectedNode = LastVisibleNode; 403 } else { 404 if (e.KeyCode == Keys.Down) 405 typesTreeView.SelectedNode = selectedNode.NextVisibleNode ?? FirstVisibleNode; // select next or cycle to first 406 if (e.KeyCode == Keys.Up) 407 typesTreeView.SelectedNode = selectedNode.PrevVisibleNode ?? LastVisibleNode; // select prev or cycle to last 408 } 409 e.Handled = true; 410 } 411 } 412 413 private TreeNode FirstVisibleNode { 414 get { 415 return typesTreeView.Nodes.Count > 0 ? typesTreeView.Nodes[0] : null; 416 } 417 } 418 private TreeNode LastVisibleNode { 419 get { 420 var node = FirstVisibleNode; 421 while (node != null && node.NextVisibleNode != null) node = node.NextVisibleNode; 422 return node; 423 } 424 } 425 426 private class ItemTreeNodeComparer : IComparer { 427 public int Compare(object x, object y) { 428 var lhs = (TreeNode)x; 429 var rhs = (TreeNode)y; 430 431 if (lhs.Tag is string && rhs.Tag is string) { 432 return lhs.Name.CompareTo(rhs.Name); 433 } else if (lhs.Tag is string) { 434 return -1; 435 } else 436 return 1; 437 } 438 } 100 439 } 101 440 }
Note: See TracChangeset
for help on using the changeset viewer.