private InspectionData GetSiblingItemFromData(InspectionData data) { if (null == data || (null == dataCollection)) { return(null); } ObservableCollection <InspectionData> collection = null; collection = (dataCollection.Data as ObservableCollection <InspectionData>); int index = collection.IndexOf(data); if (-1 == index) { return(null); } // Move to the next sibling by default. If doing so causes index // to go beyond the last valid item (not including the dummy empty // item), then move back to look for the previous item. index = index + 1; if (index >= collection.Count - 1) { index = index - 2; } if (index < 0) { return(null); // There's no sibling. } return(collection[index]); }
private void ShowVariableEditBox(string initialString) { // Only clicking on the top-most level item should bring up edit box. InspectionViewItem parent = ContainerFromItem(null, inspectionView.SelectedItem); if (null == parent || (0 != parent.Level)) { return; } currentEditingData = (InspectionData)inspectionView.SelectedItem; TextBlock nameBlock = FindDescendant <TextBlock>(parent); if (nameBlock != null) { txtVariableEditor.Height = nameBlock.Height; txtVariableEditor.Width = colName.Width; GeneralTransform transform = parent.TransformToAncestor(inspectionView); Point leftTopCoords = transform.Transform(new Point(0, 0)); if (string.IsNullOrEmpty(initialString)) { initialString = currentEditingData.DisplayText; } txtVariableEditor.Margin = new Thickness(2, leftTopCoords.Y, 0, 0); txtVariableEditor.Text = initialString; txtVariableEditor.Visibility = Visibility.Visible; txtVariableEditor.Focus(); txtVariableEditor.SelectAll(); } }
private void OnWatchWindowMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { InspectionData itemSelected = (InspectionData)inspectionView.SelectedItem; string newQualifiedName = string.Empty; if (null != itemSelected) { newQualifiedName = itemSelected.GetQualifiedName(); } if (currentQualifiedName == newQualifiedName) { return; } // Unhighlight through the current qualified name, if any. if (string.IsNullOrEmpty(currentQualifiedName) == false) { HighlightQualifiedName(currentQualifiedName, false); } // Highlight the new qualified name... currentQualifiedName = string.Empty; if (string.IsNullOrEmpty(newQualifiedName) == false) { if (HighlightQualifiedName(newQualifiedName, true)) { currentQualifiedName = newQualifiedName; } } }
internal InspectionData AddDerivation(string childExpression, int childIndexer) { if (null == derivations) { derivations = new ObservableCollection <InspectionData>(); } InspectionData data = new InspectionData(this, childExpression, childIndexer); derivations.Add(data); return(data); }
private void OnDeleteClicked(object sender, RoutedEventArgs e) { InspectionData removedItem = (InspectionData)inspectionView.SelectedItem; if (removedItem != null) { if (dataCollection.RemoveInspectionData(inspectionView.SelectedItem)) { Solution.Current.RemoveWatchExpressions(removedItem.DisplayText); inspectionView.Items.Refresh(); } } }
private void HideVariableEditBox(bool commitChanges, bool setFocusOnView) { if (null == currentEditingData) { return; // There's no editing item now. } if (currentEditingData.IsEmptyData == false) { Solution.Current.RemoveWatchExpressions(currentEditingData.Expression); } if (!string.IsNullOrEmpty(txtVariableEditor.Text) && (false != commitChanges)) { int index = dataCollection.GetParentIndex(currentEditingData); if (index >= 0 && index < dataCollection.Data.Count) { bool duplicateExpression = Solution.Current.AddWatchExpressions(txtVariableEditor.Text); if (duplicateExpression == true) { TextEditorControl.Instance.DisplayStatusMessage(StatusTypes.Info, Configurations.WatchWindowDuplicateInfo, 3); return; } dataCollection.UpdateVariableName(txtVariableEditor.Text, index); RefreshInspectionView(); } } InspectionViewItem viewItem = ContainerFromItem(null, currentEditingData); currentEditingData = null; if (null != viewItem) { viewItem.IsSelected = true; } txtVariableEditor.Visibility = Visibility.Hidden; UIElement elementToFocus = inspectionView; if (false != setFocusOnView) { elementToFocus = TextEditorControl.Instance.textCanvas; } elementToFocus.Focus(); }
private InspectionViewItem ContainerFromItem(InspectionData inspectionData) { List <InspectionData> reversedDataList = new List <InspectionData>(); InspectionData currentData = inspectionData; while (null != currentData) { reversedDataList.Insert(0, currentData); currentData = currentData.ParentData; } InspectionViewItem viewItem = null; foreach (InspectionData data in reversedDataList) { viewItem = ContainerFromItem(viewItem, data); } return(viewItem); }
/// <summary> /// Event trigger when a keyboard button is pressed in the watch window /// </summary> /// <param name="sender"></param> /// <param name="e"> /// Keys accepted: /// Delete - to delete an item in the watch window /// Enter - to bring up the editing textbox for watch variables /// </param> private void OnWatchWindowKeyDown(object sender, KeyEventArgs e) { // Method to delete items from the watch window if (e.Key == Key.Delete) { InspectionData selectedData = inspectionView.SelectedItem as InspectionData; InspectionViewItem parent = ContainerFromItem(null, selectedData); if (null != parent && parent.Level == 0) { // Get the sibling item so that we can move selection on it later. InspectionData siblingData = GetSiblingItemFromData(selectedData); InspectionData removedItem = (InspectionData)inspectionView.SelectedItem; if (dataCollection.RemoveInspectionData(inspectionView.SelectedItem)) { Solution.Current.RemoveWatchExpressions(removedItem.DisplayText); inspectionView.Items.Refresh(); } // Set focus back to the item. InspectionViewItem siblingItem = ContainerFromItem(null, siblingData); if (null != siblingItem) { siblingItem.IsSelected = true; } } } // Method to allow user to bring up the editing textbox in the // watch window. This makes usage of watch window easy else if (e.Key == Key.Enter) { ShowVariableEditBox(null); } else if (e.Key >= Key.A && (e.Key <= Key.Z)) { char character = TextEditorControl.GetKeyboardCharacter(e); ShowVariableEditBox(new string(character, 1)); } }
// This is only to be called from AddDerivation. private InspectionData(InspectionData parentData, string expression, int indexer) { this.arrayIndexer = indexer; this.parentData = parentData; SetInitialExpression(expression); }
/// <summary> /// This method retrieves the InspectionObject for a variable at any level of the watch window. /// Eg:- a /// - b /// - c /// - d /// The object for 'd' would be retrieved in a two step process /// 1. The top most parent is retrieved using the GetTopMostParent method - in this case 'a' /// 2. The GetTopMostParent method also tells you if the variable searched for is in the top level or inside /// a child. In this case, bool IsInChild is set to true /// 3. Method GetChildObject is used to retrieve the child recursively /// /// This is done because the ChildObject cannot be located without the topmost parent Obj /// </summary> /// <param name="data"> InspectionData object of the variable being searched </param> /// <returns> ProtoCore.Lang.Obj object returned for found variable </returns> private ProtoCore.Lang.Obj GetInnerInspectionObject(InspectionData data) { bool IsInChild = false; string parent = GetTopMostParent(data, out IsInChild); ProtoCore.Lang.Obj parentObj = GetStackValue(parent); if (!IsInChild) return parentObj; else return GetChildObject(parentObj, data); }
/// <summary> /// Recursively go down the Variable tree child by child till the desired /// searched data is met. /// </summary> /// <param name="parentObj"> Obj object of the parent of the child being searched </param> /// <param name="searchedData"> Variable being searched to match child object </param> /// <param name="dataSet"> /// if equal to null, it means topmost level parent (dataCollection) /// Otherwise send in the InspectedData.Derivations of the child /// </param> /// <returns></returns> private ProtoCore.Lang.Obj GetChildObject(ProtoCore.Lang.Obj parentObj, InspectionData searchedData, ObservableCollection<InspectionData> dataSet = null) { if (dataSet == null) dataSet = dataCollection; foreach (InspectionData item in dataSet) { if ((item.Expression == searchedData.Expression) && (item.Value == searchedData.Value) && (item.Type == searchedData.Type)) { return parentObj; } else if (item.HasItems) { if (item.Type == "array") { List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(parentObj); foreach (ProtoCore.Lang.Obj element in arrayElements) { ProtoCore.Lang.Obj child = GetChildObject(element, searchedData, item.Derivations); if (null != child) return child; } } else { Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(parentObj); if (null != classProperties) { foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties) { ProtoCore.Lang.Obj child = GetChildObject(property.Value, searchedData, item.Derivations); if (null != child) return child; } } } } } return null; }
private void ExpandClassInspectionData(InspectionData selectedData) { // Expansion for a class and class properties ProtoCore.Lang.Obj stackValue = GetStackValue(selectedData.Name); Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(stackValue); if (null != classProperties) { ObservableCollection<InspectionData> oldDerivations = selectedData.Derivations; selectedData.ClearDerivations(); int index = 0; foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties) { InspectionData inspectionData = CreateInspectionData(property.Value, property.Key); if (null != inspectionData) { selectedData.AddDerivation(inspectionData); if (null != oldDerivations && (index < oldDerivations.Count)) inspectionData.IsExpanded = oldDerivations[index].IsExpanded; } index = index + 1; } } }
//Recursive system to run through all branches of variable inspected public InspectionData MakeInspectionData(ProtoCore.Lang.Obj inspectionObj, string variableName, int limit = 100) { string stackValueType = GetStackValueType(inspectionObj); InspectionData inspectedScope = null; if (stackValueType == "int" || stackValueType == "double" || stackValueType == "null" || stackValueType == "bool") { string n = variableName; string v = (inspectionObj.Payload == null) ? ("null") : (inspectionObj.Payload.ToString()); string t = stackValueType; inspectedScope = new InspectionData(n, v, t); } else if (stackValueType == "array") { string n = variableName; string t = stackValueType; List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(inspectionObj); int arrayIndex = 0; string v = stackValueType + "[" + arrayElements.Count + "]"; inspectedScope = new InspectionData(n, v, t); foreach (ProtoCore.Lang.Obj element in arrayElements) { string arrayName = variableName + "[" + arrayIndex + "]"; inspectedScope.AddDerivation(MakeInspectionData(element, arrayName)); arrayIndex++; } } else { Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(inspectionObj); if (null != classProperties) { string n = variableName; string v = stackValueType; string t = stackValueType; inspectedScope = new InspectionData(n, v, t); foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties) { string propName = property.Key; inspectedScope.AddDerivation(MakeInspectionData(property.Value, propName)); } } } return inspectedScope; }
/// <summary> /// Method to create an inspection data out of a sent variable by talking /// to the Virtual machine. The watch window adds the variable with a dummy layer under the expansion. /// The dummy level prevents the Virtual Machine being called too many times, /// and should never be shown to the user. /// Eg: Variable name: 'a' /// In watch window: /// Name |Value|Type /// 'a' /// - 'This' 'is' 'dummy' /// </summary> /// <param name="inspectionObj"> Obj type retrieved from Virtual Machine for given variable </param> /// <param name="variableName"> Name of the variable to be made into InspectionData </param> /// <returns> InspectionData object of the Variable </returns> private InspectionData CreateInspectionData(ProtoCore.Lang.Obj inspectionObj, string variableName) { string stackValueType = GetStackValueType(inspectionObj); InspectionData inspectedScope = null; if (stackValueType == "int" || stackValueType == "double" || stackValueType == "null" || stackValueType == "bool") { string n = variableName; string v = (inspectionObj.Payload == null) ? ("null") : (inspectionObj.Payload.ToString()); string t = stackValueType; inspectedScope = new InspectionData(n, v, t); } else if (stackValueType == "array") { string n = variableName; string t = stackValueType; List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(inspectionObj); int arrayIndex = 0; foreach (ProtoCore.Lang.Obj element in arrayElements) { string arrayName = variableName + "[" + arrayIndex + "]"; arrayIndex++; } string v = stackValueType + "[" + arrayElements.Count + "]"; inspectedScope = new InspectionData(n, v, t); if (arrayElements.Count > 0) { // By adding "this is dummy" into the watch window we aim to prevent overworking the // Virtual Machine and expand only if necessary. Obviously, the user should NEVER see this // so that will be a defect, if ever. This also notifies the XAML binding to show the [+] // next to the watch variable. inspectedScope.AddDerivation(new InspectionData(n, v, t)); } } else { Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(inspectionObj); if (null != classProperties) { foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties) { string propName = property.Key; } string n = variableName; string v = stackValueType; string t = stackValueType; inspectedScope = new InspectionData(n, v, t); if (classProperties.Count > 0) inspectedScope.AddDerivation(new InspectionData(n, v, t)); } } return inspectedScope; }
/// <summary> /// 'Expander' is part of the toggle button defined in the XAML that shows the [+] or [-] /// sign when there are items under the current watch variable that can be inspected. /// To maximise efficiency, the expansion of items must happen only when the expander is clicked /// when showing [+]. This generated the child items from the Virtual Machine. /// </summary> /// <param name="sender"> The sender is the Toggle Button</param> /// <param name="e"></param> private void OnExpanderClicked(object sender, RoutedEventArgs e) { ToggleButton expanderToggle = (ToggleButton)sender; if (null == expanderToggle) { return; } // The parent we are trying to locate here is the InspectionViewItem. The // expander is buried beneath several layers of stackpanels and grids under the Item // and therefore we have to make numerous calls to find the InspectionViewItem. InspectionViewItem parent = (InspectionViewItem)VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent(expanderToggle)))))); object data = ((null == parent) ? null : parent.DataContext); InspectionData selectedData = data as InspectionData; if (null == selectedData) { return; } // expanderToggle.IsChecked == true means the [+] --> [-] if (expanderToggle.IsChecked == true) { parent.IsExpanded = false; dataCollection.ExpandInspection(selectedData); parent.IsExpanded = true; UpdateExpansionStates(); inspectionView.Items.Refresh(); DoExpansion(dataCollection.Data); #if false parent.IsExpanded = false; InspectionData selectedData = (InspectionData)parent.DataContext; dataCollection.ExpandInspection(selectedData); // If there is a large amount of data, the user may have to wait. // This is indicated by updating the mouse cursor. Mouse.SetCursor(Cursors.Wait); parent.IsSelected = true; parent.IsExpanded = true; selectedData.IsExpanded = true; UpdateExpansionStates(); inspectionView.Items.Refresh(); DoExpansion(dataCollection.Data); Mouse.SetCursor(Cursors.Arrow); #endif } // Select the item that is currently being expanded/collapsed. InspectionViewItem itemToSelect = ContainerFromItem(selectedData); if (null != itemToSelect) { itemToSelect.IsSelected = true; } }
/// <summary> /// Method to add new inspection data to the Watch Window/ToolTip /// This method uses the CreateInspectionData method to populate the information /// </summary> /// <param name="variableName"> Name of the variable to be added </param> /// <returns> /// True - if successfully added /// False - if exception was thrown /// </returns> public bool AddInspectionData(string variableName, bool isToolTip) { inspectionToolTip = isToolTip; if (false != inspectionToolTip) dataCollection.Clear(); if (string.IsNullOrWhiteSpace(variableName)) return false; // Always leave last item as blank data InspectionData data = new InspectionData(variableName); if (dataCollection.Count == 0) dataCollection.Add(data); else dataCollection.Insert(dataCollection.Count - 1, data); // Inspection tool tip requires immediate validation. if (false != inspectionToolTip) CreateDataRecursive(data, GetStackValue(variableName)); return true; #if false if (isToolTip) { toolTips = true; dataCollection.Clear(); } if (string.IsNullOrWhiteSpace(variableName)) return false; ProtoCore.Lang.Obj stackValue = null; InspectionParser parser = new InspectionParser(variableName); variableName = variableName.Trim(); bool limit = false; int limitValue = 0; if (parser.NeedsParsing()) { List<string> parsedCommands = parser.GetParsedCommands(); if (parser.IsValid == true) { stackValue = GetParsedObject(parsedCommands, out limit); if (limit) { string val = parsedCommands[parsedCommands.Count - 1].Replace(",", string.Empty); limitValue = Convert.ToInt32(val); } } else stackValue = null; } else { stackValue = GetStackValue(variableName); } if (stackValue == null) { //Throw exceptions string n = variableName; string v = GetStackValuePayload(n); string t = GetStackValueType(n); // Always leave last item as blank data if (dataCollection.Count != 0) dataCollection.Insert(dataCollection.Count - 1, new InspectionData(n, v, t)); else dataCollection.Add(new InspectionData(n, v, t)); return false; } else { //Get actual data InspectionData inspectedData; inspectedData = CreateInspectionData(stackValue, variableName); if (dataCollection.Count != 0) dataCollection.Insert(dataCollection.Count - 1, inspectedData); else dataCollection.Add(inspectedData); return true; } #endif }
private void CreateDataRecursive(InspectionData inspectionData, ProtoCore.Lang.Obj stackValue) { if (null == stackValue || null == stackValue.Payload) { inspectionData.Type = string.Empty; inspectionData.Value = string.Empty; if (!string.IsNullOrEmpty(inspectionData.DisplayText)) inspectionData.Value = "null"; inspectionData.ClearDerivations(); return; } inspectionData.OpType = stackValue.DsasmValue.optype; switch (stackValue.DsasmValue.optype) { case ProtoCore.DSASM.AddressType.ArrayPointer: // Array type { inspectionData.Type = "array"; inspectionData.Value = "array"; if (false == inspectionData.IsExpanded) { // If we are looking at an array, then make sure it // at least have an empty child data (so that HasItems // property returns "true"). This child data can later // be replaced by the actual value upon expansion. if (false == inspectionData.HasItems) { string parentExpression = inspectionData.Expression; inspectionData.AddDerivation(parentExpression, 0); } } else { List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(stackValue); int elementCount = ((null == arrayElements) ? 0 : arrayElements.Count); inspectionData.Type = string.Format("array[{0}]", elementCount); inspectionData.Value = inspectionData.Type; if (inspectionData.Derivations != null) ShrinkDerivations(inspectionData, elementCount); int elementsToDisplay = elementCount; if (inspectionData.ExpansionLimit > 0) { elementsToDisplay = inspectionData.ExpansionLimit; if (elementsToDisplay > elementCount) elementsToDisplay = elementCount; } string parentExpression = inspectionData.Expression; for (int index = 0; index < elementsToDisplay; ++index) { InspectionData childData = inspectionData.GetDrivationAtIndex(index); if (null == childData) childData = inspectionData.AddDerivation(parentExpression, index); CreateDataRecursive(childData, arrayElements[index]); } } break; } case ProtoCore.DSASM.AddressType.Pointer: // Class type { if (inspectionData.Expression.Equals("this") && (Int64)stackValue.Payload == -1) { inspectionData.Type = "Invalid"; inspectionData.Value = "null"; break; } inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValueData(stackValue); if (false == inspectionData.IsExpanded) { // If we are looking at a class, then make sure it // at least have an empty child data (so that HasItems // property returns "true"). This child data can later // be replaced by the actual value upon expansion. if (false == inspectionData.HasItems) inspectionData.AddDerivation(string.Empty, -1); } else { // Expansion for a class and class properties Dictionary<string, ProtoCore.Lang.Obj> properties = GetClassProperties(stackValue); if (null == properties || (properties.Count <= 0)) return; if (inspectionData.Derivations != null) ShrinkDerivations(inspectionData, properties.Count); int index = 0; foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in properties) { InspectionData childData = inspectionData.GetDrivationAtIndex(index); if (null == childData) childData = inspectionData.AddDerivation(property.Key, -1); // The first child data that was created before this class gets // expanded may not have the appropriate expression to begin with, // so set it here... childData.Expression = property.Key; if (null != property.Value) CreateDataRecursive(childData, property.Value); else { // This may be an external property, try evaluating it for value. string qualifiedName = childData.GetQualifiedName(); ProtoCore.Lang.Obj childStackValue = GetStackValue(qualifiedName); CreateDataRecursive(childData, childStackValue); } index = index + 1; } } break; } case ProtoCore.DSASM.AddressType.String: case ProtoCore.DSASM.AddressType.Char: { inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValueData(stackValue); inspectionData.ClearDerivations(); break; } default: // This applies to all other primitive types. { inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValuePayload(stackValue); inspectionData.ClearDerivations(); break; } } }
/// <summary> /// This method is used to retrieve the index of an item that is selected. This method /// will only return the Parent Index of the selected so child items will return -1 /// </summary> /// <param name="item"> InspectionData item selected </param> /// <returns></returns> public int GetParentIndex(InspectionData itemSelected) { int index = 0; foreach (InspectionData data in dataCollection) { if (itemSelected.Expression == data.Expression && itemSelected.Value == data.Value && itemSelected.Type == data.Type) { break; } index++; } // The item selected is either not a parent item or doesn't exist if (index >= dataCollection.Count) return -1; return index; }
/// <summary> /// This method is hit on one condition: the variable CAN be expanded by pressing the [+] /// symbol in the watch window. This means some sort of expansion should replace the silly old /// 'This is dummy' and populate it. This method goes about populating the selectedData.Derivations /// for arrays and classes (which are the only expandable variables in a watch window). /// For arrays, this method also tests if the array is larger than a certain value, indicating to /// the user that it may take some time to expand. /// </summary> /// <param name="selectedData"> InspectionData object of the variable that is to be expanded</param> public void ExpandInspection(InspectionData selectedData) { selectedData.IsExpanded = true; string qualifiedName = selectedData.GetQualifiedName(); ProtoCore.Lang.Obj stackValue = GetStackValue(qualifiedName); CreateDataRecursive(selectedData, stackValue); #if false ProtoCore.Lang.Obj dataObj = null; // Use Inspection Parser to parse the string to decipher what kind of expansion required InspectionParser parser = new InspectionParser(selectedData.Name); bool limit = false; int limitValue = 0; List<string> parsedCommands = null; // An inspection variable needs parsing when it contains: // [] (array) and/or // '.' (class properties) and/or // ',' (limit) if (parser.NeedsParsing()) { parsedCommands = parser.GetParsedCommands(); if (parser.IsValid == true) { // Use GetParsedObject method to decipher Obj from parsed string dataObj = GetParsedObject(parsedCommands, out limit); // A limit is indicated by a comma (,) if (limit) { // The limit should ALWAYS be the last item in parsed commands string val = parsedCommands[parsedCommands.Count - 1].Replace(",", string.Empty); limitValue = Convert.ToInt32(val); } } else dataObj = null; } else { dataObj = GetInnerInspectionObject(selectedData); } // If, from any level above the dataObj is null, throw an exception if (dataObj == null) { //Throw exceptions string n = selectedData.Name; string v = GetStackValuePayload(n); string t = GetStackValueType(n); // Replace the current data with the exceptions relevant for it RemoveInspectionData(selectedData); dataCollection.Insert(dataCollection.Count - 1, new InspectionData(n, v, t)); } // Otherwise expand it by one more level yo! else { if (selectedData.Type == "array") ExpandArrayInspectionData(selectedData, limit); else ExpandClassInspectionData(selectedData); } #endif }
private void ExpandArrayInspectionData(InspectionData selectedData, bool limitExpansion) { ProtoCore.Lang.Obj stackValue = GetStackValue(selectedData.Name); List<ProtoCore.Lang.Obj> arrayStackValues = GetArrayStackValues(stackValue); ObservableCollection<InspectionData> derivations = new ObservableCollection<InspectionData>(); int arrayIndex = 0; // Give user a notification if a large number of array elements are expanded // The limit set is located at Configurations.InspectionArrayLimit if ((arrayStackValues.Count > Configurations.InspectionArrayLimit) && !limitExpansion) { string message = "This array has a large number of items. Displaying may take several seconds. " + "Show all elements anyway? Alternatively you can choose 'No' and limit your array expansion " + "by adding a comma (,) after your variable followed by the number of elements to be shown."; MessageBoxResult result = MessageBox.Show(message, "Inspection", MessageBoxButton.YesNo); // If user chooses 'Yes' expand all items if (result == MessageBoxResult.Yes) { foreach (ProtoCore.Lang.Obj element in arrayStackValues) { // Array name should be represented like a[3] for each element string arrayName = (limit ? parsedCommands[0] : selectedData.Name) + "[" + arrayIndex + "]"; derivations.Add(CreateInspectionData(element, arrayName)); arrayIndex++; if ((limit) && (derivations.Count > limitValue)) { break; } } // Value for an array is represented like array[10] string v = selectedData.Type + "[" + arrayStackValues.Count + "]"; for (int i = 0; i < selectedData.Derivations.Count; i++) { if (selectedData.Derivations[i].IsExpanded == true) { if (i < derivations.Count) derivations[i].IsExpanded = true; } } selectedData.Derivations = derivations; } } // If there was no limit reached, proceed as normal else { foreach (ProtoCore.Lang.Obj element in arrayStackValues) { string arrayName = (limit ? parsedCommands[0] : selectedData.Name) + "[" + arrayIndex + "]"; derivations.Add(CreateInspectionData(element, arrayName)); arrayIndex++; if ((limit) && (derivations.Count > limitValue)) { break; } } string v = selectedData.Type + "[" + arrayStackValues.Count + "]"; for (int i = 0; i < selectedData.Derivations.Count; i++) { if (selectedData.Derivations[i].IsExpanded == true) { if (i < derivations.Count) derivations[i].IsExpanded = true; } } selectedData.Derivations = derivations; } }
private void ShrinkDerivations(InspectionData inspectionData, int elementCount) { for (int i = inspectionData.Derivations.Count - 1; i >= elementCount; i--) inspectionData.Derivations.RemoveAt(i); }
/// <summary> /// Retrieves the top-most parent for any InspectionData variable /// </summary> /// <param name="dataSearched"> InspectionData variable being searched </param> /// <param name="IsInChild"> out parameter that toggles to false if top most parent is dataSearched, else false</param> /// <returns> Name of topmost parent of variable </returns> private string GetTopMostParent(InspectionData dataSearched, out bool IsInChild) { foreach (InspectionData item in dataCollection) { if (CheckChildren(item.Derivations, dataSearched) == true) { IsInChild = true; return item.Expression; } else if ((item.Expression == dataSearched.Expression) && (item.Value == dataSearched.Value) && (item.Type == dataSearched.Type)) { IsInChild = false; return item.Expression; } } IsInChild = false; return null; }
/// <summary> /// Recursively go down the Variable tree child by child to see if there is a valid child in the dataSet /// </summary> /// <param name="dataSet"> /// if equal to null, it means there is no further dataSet to search so return false /// Else, send in InspectionData.Derivations /// </param> /// <param name="dataSearched"> InspectionData variable being searched </param> /// <returns> True id a child is found, false if no child</returns> private bool CheckChildren(ObservableCollection<InspectionData> dataSet, InspectionData dataSearched) { if (dataSet == null) return false; foreach (InspectionData item in dataSet) { if ((item.Expression == dataSearched.Expression) && (item.Value == dataSearched.Value) && (item.Type == dataSearched.Type)) { return true; } else if (item.HasItems) { return CheckChildren(item.Derivations, dataSearched); } } return false; }
internal InspectionData AddDerivation(string childExpression, int childIndexer) { if (null == derivations) derivations = new ObservableCollection<InspectionData>(); InspectionData data = new InspectionData(this, childExpression, childIndexer); derivations.Add(data); return data; }