/// <summary> /// Writes serialized KmlItem into writer /// </summary> /// <param name="writer">Writer used to write serialized item.</param> /// <param name="item">Item for serialization.</param> /// <param name="indent">Default indent.</param> public static void WriteItem(TextWriter writer, KmlItem item, int indent) { bool ghost = item is KmlGhostNode; if (!ghost) { writer.WriteLine(item.ToLine(indent)); } if (item is KmlNode) { int newIndent = indent; KmlNode node = (KmlNode)item; if (!ghost) { writer.WriteLine(new KmlBegin().ToLine(indent)); newIndent = indent + 1; } foreach (KmlItem child in node.AllItems) { WriteItem(writer, child, newIndent); } if (!ghost) { writer.WriteLine(new KmlEnd().ToLine(indent)); } } }
private void AddAttrib(KmlNode toItem, KmlAttrib beforeItem) { KmlNode node = toItem; string input; string preset = ""; bool loop = true; while (loop && DlgInput.Show("Enter the name for the new attribute:", "NEW attribute", Icons.Add, preset, out input)) { string attrib = input; if (attrib.Length > 0 && attrib.IndexOf('=') < 0) { attrib = attrib + "="; } KmlItem item = KmlItem.CreateItem(attrib); if (item is KmlAttrib && beforeItem != null) { node.InsertBefore(beforeItem, (KmlAttrib)item); loop = false; // View will be refreshed in AttribChanged event } else if (item is KmlAttrib) { node.Add((KmlAttrib)item); loop = false; // View will be refreshed in AttribChanged event } else { DlgMessage.Show("Attribute name is not allowed to be empty or contain following characters: {}", "NEW attribute", Icons.Warning); preset = input; // Input will pop up again while loop == true } } }
/// <summary> /// Load a KML structure from data file into tree. /// </summary> /// <param name="filename">The full path and filename of the data file to read</param> public void Load(string filename) { Tree.Items.Clear(); TreeDetails.Items.Clear(); KmlRoots = KmlItem.ParseFile(filename); // Check if any of these roots is not a node // If so, pack all roots into a new ghost root if (KmlRoots.Any(x => !(x is KmlNode))) { KmlGhostNode root = new KmlGhostNode(System.IO.Path.GetFileName(filename), null); root.AddRange(KmlRoots); KmlRoots.Clear(); KmlRoots.Add(root); } foreach (KmlItem item in KmlRoots) { if (item is KmlNode) { Tree.Items.Add(new GuiTreeNode((KmlNode)item)); } } if (Tree.Items.Count >= 1) { TreeViewItem item = (TreeViewItem)Tree.Items[0]; item.IsSelected = true; if (Tree.Items.Count == 1) { item.IsExpanded = true; } } }
private void AddChildNode(KmlNode toItem, KmlNode beforeItem) { KmlNode node = toItem; string input; string preset = ""; bool loop = true; while (loop && DlgInput.Show("Enter the tag for the new node:", "NEW node", Icons.Add, preset, out input)) { KmlItem item = KmlItem.CreateItem(input); if (item is KmlNode && beforeItem != null) { node.InsertBefore(beforeItem, (KmlNode)item); loop = false; // View will be refreshed in ChildrenChanged event } else if (item is KmlNode) { node.Add((KmlNode)item); loop = false; // View will be refreshed in ChildrenChanged event } else { DlgMessage.Show("Tag is not allowed to be empty or contain following characters: ={}", "NEW node", Icons.Warning); preset = input; // Input will pop up again while loop == true } } }
/// <summary> /// Deletes a KmlItem from this nodes lists. /// Result will be false if item was not in the lists or couldn't be deleted /// because of restrictions. /// </summary> /// <param name="item">The KmlItem to delete</param> /// <returns>True if item was deleted, false otherwise</returns> public virtual bool Delete(KmlItem item) { if (!item.CanBeDeleted) { return(false); } // Call itme's Delete to call it's BeforeDelete() // But there would usually be called this method, // to avoid loop we set parent to null. // We also ignore result, will be false in that case RemapParent(item, null); item.Delete(); if (!AllItems.Remove(item)) { // It wasn't in the list, nothing to do return(false); } if (item is KmlAttrib) { bool result = Attribs.Remove((KmlAttrib)item); InvokeAttribChanged(); return(result); } else if (item is KmlNode) { bool result = Children.Remove((KmlNode)item); InvokeChildrenChanged(); return(result); } else { return(Unknown.Remove(item)); } }
/// <summary> /// Creates a KmlItem from a string. /// This is used for adding items outside of loading from file. /// Result will be a KmlAttrib, KmlNode, KmlVessel, etc. or null /// if line is "{", "}" or empty /// </summary> /// <param name="line">The line to build a KmlItem from</param> /// <returns>A KmlItem derived object</returns> public static KmlItem CreateItem(string line) { if (line == null || line.Length == 0) { return(null); } else if (line.IndexOf('{') >= 0) { return(null); } else if (line.IndexOf('}') >= 0) { return(null); } KmlItem item = ParseLine(line); if (item is KmlAttrib) { return(item); } else { // It's a node return(ParseNode(item)); } }
/// <summary> /// Adds each KmlItem in the list before KmlItem like InsertBefore(KmlItem, KmlItem) does. /// <see cref="KML.KmlNode.InsertBefore(KML.KmlItem, KML.KmlItem)"/> /// </summary> /// <param name="beforeItem">The KmlItem where the new item should be inserted before</param> /// <param name="list">A List of KmlItem to add</param> public void InsertBeforeRange(KmlItem beforeItem, List <KmlItem> list) { foreach (KmlItem item in list) { Add(beforeItem, item); } }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> /// <returns>Whether item was found or not</returns> public bool Select(KmlItem item) { KmlNode masterNode = item is KmlNode ? (KmlNode)item : item.Parent; foreach (GuiKerbalsNode node in KerbalsList.Items) { if (node.DataKerbal == masterNode) { // Force a refreh, by causing SelectionChanged to invoke KerbalsList.SelectedItem = null; KerbalsList.SelectedItem = node; KerbalsList.ScrollIntoView(node); Focus(); if (item is KmlAttrib) { foreach (GuiTreeAttrib attrib in KerbalsDetails.Items) { if (attrib.DataAttrib == item) { attrib.IsSelected = true; KerbalsDetails.Focus(); } } } return(true); } } return(false); }
private static void WriteFile(StreamWriter file, KmlItem item, int indent) { bool ghost = item is KmlGhostNode; if (!ghost) { file.WriteLine(item.ToLine(indent)); } if (item is KmlNode) { int newIndent = indent; KmlNode node = (KmlNode)item; if (!ghost) { file.WriteLine(new KmlBegin().ToLine(indent)); newIndent = indent + 1; } foreach (KmlItem child in node.AllItems) { WriteFile(file, child, newIndent); } if (!ghost) { file.WriteLine(new KmlEnd().ToLine(indent)); } } }
private bool SelectSearch(Stack <KmlNode> stack, KmlItem item) { KmlNode node = stack.Peek(); foreach (KmlItem sub in node.AllItems) { if (sub == item) { return(true); } else if (sub is KmlNode) { stack.Push(sub as KmlNode); if (SelectSearch(stack, item)) { return(true); } else { stack.Pop(); } } } return(false); }
private void KerbalsList_SelectionChanged(object sender, SelectionChangedEventArgs e) { // Store currently selected attribute, in case we just unselect + select the current item to refresh if (KerbalsList.SelectedItem == null) { // We're unselcting, this is the old data we want to restore in future call of this event GuiTreeAttrib attrib = (KerbalsDetails.SelectedItem as GuiTreeAttrib); if (attrib == null) { _oldSelectedAttrib = null; _alternativeSelectedAttrib = null; } else { _oldSelectedAttrib = attrib.DataAttrib; int i = KerbalsDetails.SelectedIndex; if (i < KerbalsDetails.Items.Count - 1) { _alternativeSelectedAttrib = (KerbalsDetails.Items[i + 1] as GuiTreeAttrib).DataAttrib; } else if (i > 0) { _alternativeSelectedAttrib = (KerbalsDetails.Items[i - 1] as GuiTreeAttrib).DataAttrib; } else { _alternativeSelectedAttrib = null; } } } KerbalsDetails.Items.Clear(); if (KerbalsList.SelectedItem != null) { GuiKerbalsNode Node = (GuiKerbalsNode)KerbalsList.SelectedItem; KerbalsDetails.ContextMenu = Node.ContextMenu; foreach (KmlAttrib attrib in Node.DataKerbal.Attribs) { KerbalsDetails.Items.Add(new GuiTreeAttrib(attrib)); } _oldSelectedKerbal = Node.DataKerbal; // Restore attrib selection if (Node.DataKerbal == _oldSelectedKerbal && _oldSelectedAttrib != null) { if (!Select(_oldSelectedAttrib)) { Select(_alternativeSelectedAttrib); } if (KerbalsDetails.SelectedItem != null) { (KerbalsDetails.SelectedItem as ListViewItem).Focus(); } } } else { KerbalsDetails.ContextMenu = null; } }
/// <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> /// Show a search dialog. /// </summary> /// <param name="left">The left coordinate for the dialog</param> /// <param name="top">The top coordinate for the dialog</param> /// <param name="selectedItem">Out: Returns the selected KmlItem if "Ok" was clicked, null otherwise</param> /// <param name="presetText">The preset text to search for</param> /// <returns>True if "Ok" was clicked, false otherwise</returns> public static bool Show(double left, double top, out KmlItem selectedItem, string presetText = null) { DlgSearch dlg = new DlgSearch(presetText); dlg.Left = left; dlg.Top = top; return(dlg.Show(out selectedItem)); }
private static List <KmlItem> ParseFile(System.IO.StreamReader file, KmlNode parent) { List <KmlItem> list = new List <KmlItem>(); string line; while ((line = file.ReadLine()) != null) { KmlItem newItem = ParseLine(line); if (newItem is KmlBegin) { KmlItem lastItem; int l = list.Count - 1; if (l < 0) { lastItem = new KmlItem(""); } else { lastItem = list[l]; list.RemoveAt(l); } KmlNode newNode = new KmlNode(lastItem, parent); if (newNode.Tag.ToLower() == "vessel") { newNode = new KmlVessel(newNode); } else if (newNode.Tag.ToLower() == "kerbal") { newNode = new KmlKerbal(newNode); } else if (newNode.Tag.ToLower() == "part") { newNode = new KmlPart(newNode); } else if (newNode.Tag.ToLower() == "resource") { newNode = new KmlResource(newNode); } list.Add(newNode); newNode.AddRange(ParseFile(file, newNode)); } else if (newItem is KmlEnd) { Identify(list); return(list); } else { list.Add(newItem); } } Identify(list); return(list); }
/// <summary> /// Get previous result from last search. /// </summary> /// <returns>The previous KmlItem from search</returns> public static KmlItem SearchPrevious() { int i = _searchResults.IndexOf(_selectedItem); if (i > 0 && i < _searchResults.Count) { _selectedItem = _searchResults[i - 1]; } return(_selectedItem); }
/// <summary> /// Get next result from last search. /// </summary> /// <returns>The next KmlItem from search</returns> public static KmlItem SearchNext() { int i = _searchResults.IndexOf(_selectedItem); if (i >= 0 && i < _searchResults.Count - 1) { _selectedItem = _searchResults[i + 1]; } return(_selectedItem); }
/// <summary> /// Adds a child KmlItem to this nodes lists of children, depending of its /// derived class KmlNode, KmlAttrib or further derived from these. /// When an KmlAttrib "Name", "Type" or "Trait" are found, their value /// will be used for the corresponding property of this node. /// </summary> /// <param name="beforeItem">The KmlItem where the new item should be inserted before</param> /// <param name="newItem">The KmlItem to add</param> protected override void Add(KmlItem beforeItem, KmlItem newItem) { if (newItem is KmlAttrib) { KmlAttrib attrib = (KmlAttrib)newItem; if (attrib.Name.ToLower() == "name" && Name.Length == 0) { // Name property is managed by KmlNode, // but we need another method to be called on name change event // to rename the crew attrib in assigned vessel part also attrib.AttribValueChanged += CrewName_Changed; } else if (attrib.Name.ToLower() == "type" && Type.Length == 0) { Type = attrib.Value; // Get notified when Type changes attrib.AttribValueChanged += Type_Changed; attrib.CanBeDeleted = false; } else if (attrib.Name.ToLower() == "trait" && Trait.Length == 0) { Trait = attrib.Value; // Get notified when Trait changes attrib.AttribValueChanged += Trait_Changed; attrib.CanBeDeleted = false; } else if (attrib.Name.ToLower() == "state" && State.Length == 0) { State = attrib.Value; // Get notified when State changes attrib.AttribValueChanged += State_Changed; attrib.CanBeDeleted = false; } else if (attrib.Name.ToLower() == "brave" && Brave == 0.0) { Brave = GetDoubleValue(attrib.Value, Brave); // Get notified when Trait changes attrib.AttribValueChanged += Brave_Changed; attrib.CanBeDeleted = false; } else if (attrib.Name.ToLower() == "dumb" && Dumb == 0.0) { Dumb = GetDoubleValue(attrib.Value, Dumb); // Get notified when Dumb changes attrib.AttribValueChanged += Dumb_Changed; attrib.CanBeDeleted = false; } } base.Add(beforeItem, newItem); }
private void SearchAddItem(List <KmlItem> result, KmlItem item, string text, bool checkNodeTag, bool checkNodeText, bool checkAttribName, bool checkAttribValue) { if (SearchCheckItem(item, text, checkNodeTag, checkNodeText, checkAttribName, checkAttribValue)) { result.Add(item); } if (SearchCheckItem(item, text, true, true, true, true)) { _oldSearchList.Add(item); } }
/// <summary> /// Some key was pressed. /// </summary> public void CommandExec(string Command) { if (TreeDetails.IsKeyboardFocusWithin && TreeDetails.SelectedItem is GuiTreeAttrib) { if (Command == "Enter") { // Enter the TextBox for value editing TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next); (TreeDetails.SelectedItem as ListViewItem).MoveFocus(request); } else if (Command == "Escape" || Command == "Left") { // Get back to TreeView Tree.Focus(); (Tree.SelectedItem as TreeViewItem).Focus(); } else { (TreeDetails.SelectedItem as GuiTreeAttrib).CommandExec(Command); } } else if (TreeDetails.IsKeyboardFocusWithin) { // Empty details if (Command == "Left") { // Get back to TreeView Tree.Focus(); (Tree.SelectedItem as TreeViewItem).Focus(); } } else if (Tree.IsKeyboardFocusWithin && Tree.SelectedItem is GuiTreeNode) { if (Command == "Enter" && TreeDetails.HasItems) { // Switch to attributes TreeDetails.Focus(); KmlItem item = GetSelectedItem(); if (item is KmlNode) { KmlNode node = (KmlNode)item; if (node.Attribs.Count > 0) { Select(node.Attribs[0]); (TreeDetails.SelectedItem as ListViewItem).Focus(); } } } else { (Tree.SelectedItem as GuiTreeNode).CommandExec(Command); } } }
private static void Identify(List <KmlItem> list) { for (int i = 0; i < list.Count; i++) { KmlItem item = list[i]; KmlItem replaceItem = item.Identify(); if (replaceItem != null) { list[i] = replaceItem; } } }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> public void Select(KmlItem item) { foreach (GuiVesselsNode node in VesselsList.Items) { if (node.DataVessel == item) { VesselsList.SelectedItem = node; VesselsList.ScrollIntoView(node); Focus(); return; } } }
/// <summary> /// Changes the parent. Needed when a node is changed to a derived class /// and all existing children need to have a new parent. /// </summary> /// <param name="item">The KmlItem where parent needs to be changed</param> /// <param name="parent">The new parent KmlNode</param> protected static void RemapParent(KmlItem item, KmlNode parent) { if (item.Parent != parent) { // This often happens when we iterate through the lists, // so we can not delete items from that list here. // TODO KmlItem.RemapParent(): Delete item from old parent // item.Delete(); // from previous parent item.UnbindOldParent(); item.Parent = parent; item.IdentifyParent(); } }
private void ButtonPrevious_Click(object sender, RoutedEventArgs e) { KmlItem search = DlgSearch.SearchPrevious(); if (search != null) { TabsManager.TreeManager.Select(search); } else { TabsManager.Previous(); } }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> public void Select(KmlItem item) { foreach (GuiWarningsNode node in WarningsList.Items) { if (node.DataMessage.Source == item) { WarningsList.SelectedItem = node; WarningsList.ScrollIntoView(node); Focus(); return; } } }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> public void Select(KmlItem item) { foreach (GuiKerbalsNode node in KerbalsList.Items) { if (node.DataKerbal == item) { KerbalsList.SelectedItem = node; KerbalsList.ScrollIntoView(node); Focus(); return; } } }
private void AttribCopy_Click(object sender, RoutedEventArgs e) { KmlAttrib attrib = ((sender as MenuItem).DataContext as KmlAttrib); var sr = new StringWriter(); KmlItem.WriteItem(sr, attrib, 0); sr.Flush(); var textNode = sr.GetStringBuilder().ToString(); Clipboard.SetDataObject(textNode); }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> public void Select(KmlItem item) { foreach (GuiWarningsNode node in WarningsList.Items) { if (node.DataMessage.Source == item) { // Force a refreh, by causing SelectionChanged to invoke WarningsList.SelectedItem = null; WarningsList.SelectedItem = node; WarningsList.ScrollIntoView(node); Focus(); return; } } }
/// <summary> /// Select should be called from within other GuiManagers /// and wants this manager to get avtive and go to given item. /// </summary> /// <param name="item">The KmlItem to select</param> public void Select(KmlItem item) { foreach (GuiVesselsNode node in VesselsList.Items) { if (node.DataVessel == item) { // Force a refreh, by causing SelectionChanged to invoke VesselsList.SelectedItem = null; VesselsList.SelectedItem = node; VesselsList.ScrollIntoView(node); Focus(); return; } } }
/// <summary> /// Search all child nodes of this node for a certain tag and name, /// create one if not found. Does not search recursive. /// </summary> /// <param name="tag">The tag of the KmlNode to search for</param> /// <param name="name">The name of the KmlNode to search for</param> /// <returns>The found or created KmlNode</returns> public KmlNode GetOrCreateChildNode(string tag, string name) { KmlNode node = GetChildNode(tag, name); if (node == null) { node = KmlItem.CreateItem(tag) as KmlNode; if (name != null && name.Length > 0) { // Add name attribute node.Add(KmlItem.CreateItem("name=" + name)); } Add(node); } return(node); }
/// <summary> /// Search all KmlAttribs of this node, create one if not found. /// Does not search recursive. Default value will only be used on creation. /// </summary> /// <param name="name">The name of the KmlAttribs to search for</param> /// <param name="defaultValue">The default value for a created attribute</param> /// <returns>The found or created KmlAttrib</returns> public KmlAttrib GetOrCreateAttrib(string name, string defaultValue) { KmlAttrib attrib = GetAttrib(name); if (attrib == null) { string line = name + "="; if (defaultValue != null && defaultValue.Length > 0) { line += defaultValue; } attrib = KmlItem.CreateItem(line) as KmlAttrib; Add(attrib); } return(attrib); }