/// <summary> /// Adds a child KmlItem to this nodes lists of children, depending of its /// derived class KmlNode or KmlAttrib or further derived from these. /// When an KmlAttrib "Name" is found, its value will be used for the "Name" property /// of this node. /// </summary> /// <param name="item">The KmlItem to add</param> public virtual void Add(KmlItem item) { AllItems.Add(item); if (item is KmlNode) { Children.Add((KmlNode)item); } else if (item is KmlAttrib) { KmlAttrib attrib = (KmlAttrib)item; if (attrib.Name.ToLower() == "name") { Name = attrib.Value; // Get notified when Name changes attrib.AttribValueChanged += Name_Changed; attrib.CanBeDeleted = false; } Attribs.Add(attrib); } else { Unknown.Add(item); Syntax.Warning(this, "Unknown line in persistence file: " + item.ToString()); } }
/// <summary> /// Adds (inserts before) a child KmlItem to this nodes lists of children. /// If item to insert before is null or not contained, it will be added at the end. /// This is the basic add method, derived classes can override but should /// always call base.Add(beforeItem, newItem) within. /// Public Add, AddRange, InsertBefore and InsertAfter all use this protected /// method to access the lists. /// <see cref="KML.KmlNode.Add(KML.KmlItem)"/> /// </summary> /// <param name="beforeItem">The KmlItem where the new item should be inserted before</param> /// <param name="newItem">The KmlItem to add</param> protected virtual void Add(KmlItem beforeItem, KmlItem newItem) { // ensure that item.Parent is this node if (newItem.Parent != this) { RemapParent(newItem, this); } // Not add always to end of AllItems, add well ordered: attribs first, then nodes. // Like Add(attrib), Add(Node), Add(attrib) should result in attrib, attrib, node if (newItem is KmlAttrib && !(beforeItem is KmlAttrib) && Children.Count > 0) { Syntax.Warning(newItem, "KML attribute should not come after nodes, will be fixed when saved"); beforeItem = Children[0]; } if (beforeItem != null && AllItems.Contains(beforeItem)) { AllItems.Insert(AllItems.IndexOf(beforeItem), newItem); } else { AllItems.Add(newItem); } if (newItem is KmlNode) { if (beforeItem is KmlNode && Children.Contains((KmlNode)beforeItem)) { Children.Insert(Children.IndexOf((KmlNode)beforeItem), (KmlNode)newItem); } else { Children.Add((KmlNode)newItem); } InvokeChildrenChanged(); } else if (newItem is KmlAttrib) { KmlAttrib attrib = (KmlAttrib)newItem; if (attrib.Name.ToLower() == "name") { if (Name.Length == 0) { Name = attrib.Value; // Get notified when Name changes attrib.AttribValueChanged += Name_Changed; attrib.CanBeDeleted = false; // And notify that the name changed InvokeToStringChanged(); } } if (beforeItem is KmlAttrib && Attribs.Contains((KmlAttrib)beforeItem)) { Attribs.Insert(Attribs.IndexOf((KmlAttrib)beforeItem), attrib); } else { Attribs.Add(attrib); } InvokeAttribChanged(); } else { if (beforeItem != null && Unknown.Contains(newItem)) { Unknown.Insert(Unknown.IndexOf(beforeItem), newItem); } else { Unknown.Add(newItem); } Syntax.Warning(this, "Unknown line in persistence file: " + newItem.ToString()); } }
private void Search(bool continued = false) { const int SEARCHLIMIT = 100; List <KmlItem> list; // TODO DlgSearch.Search(): loading the list on every continuation isn't the best choice // but it's ok, because that is fast, only loading items into tree is slow list = GuiTabsManager.GetCurrent().TreeManager.Search(TextBoxInput.Text, CheckNodeTag.IsChecked == true, CheckNodeText.IsChecked == true, CheckAttribName.IsChecked == true, CheckAttribValue.IsChecked == true); _searchResults.Clear(); _searchResults.AddRange(list); int maxItemCount = SEARCHLIMIT; KmlNode parentNode = null; TreeViewItem parentItem = null; if (continued) { _searchContinued++; maxItemCount = SEARCHLIMIT * (_searchContinued + 1); parentItem = (TreeViewItem)Tree.Items[Tree.Items.Count - 1]; parentNode = list[maxItemCount - SEARCHLIMIT - 1].Parent; } else { _searchContinued = 0; Tree.Items.Clear(); } for (int i = maxItemCount - SEARCHLIMIT; i < list.Count; i++) { KmlItem item = list[i]; // if (Tree.Items.Count >= maxParentCount) if (i >= maxItemCount) { TreeViewItem dummy = new TreeViewItem(); dummy.Header = "..."; TreeViewItem toBeContinued = new TreeViewItem(); toBeContinued.Header = "... " + (list.Count - maxItemCount) + " more items ..."; toBeContinued.Expanded += ToBeContinued_Expanded; toBeContinued.Items.Add(dummy); Tree.Items.Add(toBeContinued); return; } if (item is KmlNode || item is KmlAttrib) { if (item.Parent != null && item.Parent != parentNode) { parentNode = item.Parent; parentItem = new TreeViewItem(); parentItem.Header = item.Parent.PathToString(@"\"); Tree.Items.Add(parentItem); parentItem.IsExpanded = true; } TreeViewItem node; if (item is KmlNode) { node = new GuiTreeNode((KmlNode)item, true, true, true, false, true, false); } else { node = new TreeViewItem(); node.DataContext = item; node.Header = item.ToString(); } node.Margin = new Thickness(-16, 0, 0, 0); if (parentNode == null) { Tree.Items.Add(node); } else { parentItem.Items.Add(node); } node.IsSelected = Tree.SelectedItem == null; } } }