/// <summary> /// Constructs a new FeatureWrapperEventArgs /// </summary> /// <param name="ftWrapper">FeatureWrapper</param> public FeatureWrapperEventArgs(FeatureWrapper ftWrapper) { if (null == ftWrapper) { throw new ArgumentNullException("ftWrapper"); } _ftWrapper = ftWrapper; }
/// <summary> /// Ripple down from the desired start point tracing and highlighting the results. /// </summary> public void TraceTriggered(FeatureWrapper feature, int unit, PortType port = PortType.Input) { try { if (null == feature) { throw new ArgumentNullException("FeatureWrapper"); } FiberCableWrapper fiberCableWrapper = feature as FiberCableWrapper; DeviceWrapper deviceWrapper = feature as DeviceWrapper; int fiberNumber = unit; _startedOnFiber = true; if (null != deviceWrapper) { fiberCableWrapper = GetConnectedFiber(deviceWrapper, unit, port, out fiberNumber); _startedOnFiber = false; } List<Range> traceRange = new List<Range>(new Range[] { new Range(fiberNumber, fiberNumber) }); if (null != fiberCableWrapper) { if (SpliceAndConnectionUtils.AreRangesWithinFiberCount(traceRange, fiberCableWrapper)) { ESRI.ArcGIS.Geodatabase.IFeature ft = fiberCableWrapper.Feature; _traceResults.Clear(); _traceResults = TracePath(ft, fiberNumber, true); _traceResults.Reverse(); // This went down the "from end", so they are backwards _startFiberIdx = _traceResults.Count; // Now add ourselves _traceResults.Add(ft); _traceResults.Add(GetFiberRecord(ft, fiberNumber)); // Now add everything going the other way List<ESRI.ArcGIS.Geodatabase.IRow> resultsAtToEnd = TracePath(ft, fiberNumber, false); _traceResults.AddRange(resultsAtToEnd); if (TraceCompleted != null) { TraceCompleted(this, null); } } else { System.Windows.Forms.MessageBox.Show("Fiber strand number is not within the fiber cable's number of fibers.", "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information); } } else { System.Windows.Forms.MessageBox.Show("No fiber cable / strand was specified, or none was connected to the specified port.", "Telecom Trace", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information); } // --------------------------------------- // This causes a refresh of the selection // and we see the results of the trace on // the map // --------------------------------------- _hookHelper.ActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null); // ActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message, "ERROR"); System.Diagnostics.Trace.WriteLine(ex.StackTrace, "DETAILS"); } finally { } }
/// <summary> /// Check changes to the grid and save them to the database /// </summary> /// <param name="from">From feature</param> /// <param name="to">To feature</param> /// <returns>Success</returns> private bool SaveChanges(FeatureWrapper from, FeatureWrapper to) { bool result = false; string isNotOkString = string.Empty; Dictionary<int, int> currentGrid = new Dictionary<int, int>(); FiberCableWrapper cable = null; DeviceWrapper device = null; bool isFromEnd = false; PortType portType = PortType.Input; #region Detect Direction try { if (from is FiberCableWrapper && to is ConnectableDeviceWrapper) { cable = cboFrom.SelectedItem as FiberCableWrapper; device = cboTo.SelectedItem as DeviceWrapper; isFromEnd = ((ConnectableDeviceWrapper)device).IsCableFromEnd; portType = PortType.Input; } else if (from is DeviceWrapper && to is ConnectableCableWrapper) { device = cboFrom.SelectedItem as DeviceWrapper; cable = cboTo.SelectedItem as FiberCableWrapper; isFromEnd = ((ConnectableCableWrapper)cable).IsThisFromEnd; portType = PortType.Output; } else { isNotOkString = "Must connect a cable to a device, or device to a cable."; } } catch (Exception ex) { isNotOkString = ex.Message; } #endregion try { if (null != cable && null != device) { // Only continue if we have a valid setup try { int aIdx = colFromRange.Index; int bIdx = colToRange.Index; // Less than count-1 lets us avoid the insert row for (int i = 0; i < grdConnections.Rows.Count - 1; i++) { object aRanges = (grdConnections[aIdx, i].Value != null ? grdConnections[aIdx, i].Value : ""); object bRanges = (grdConnections[bIdx, i].Value != null ? grdConnections[bIdx, i].Value : ""); List<Range> fromRanges = SpliceAndConnectionUtils.ParseRanges(aRanges.ToString()); List<Range> toRanges = SpliceAndConnectionUtils.ParseRanges(bRanges.ToString()); // Check that counts match up if (!SpliceAndConnectionUtils.AreCountsEqual(fromRanges, toRanges)) { isNotOkString = "Number of units from A to B must match on each row."; } // Check the ranges are within the feature's units if (PortType.Input == portType) { if (!SpliceAndConnectionUtils.AreRangesWithinFiberCount(fromRanges, cable)) { isNotOkString = "Selected units exceed fiber count for cable."; } else if (!SpliceAndConnectionUtils.AreRangesWithinPortCount(toRanges, device, portType)) { isNotOkString = "Selected units exceed input port count for device."; } } else { if (!SpliceAndConnectionUtils.AreRangesWithinFiberCount(toRanges, cable)) { isNotOkString = "Selected units exceed fiber count for cable."; } else if (!SpliceAndConnectionUtils.AreRangesWithinPortCount(fromRanges, device, portType)) { isNotOkString = "Selected units exceed output port count for device."; } } if (0 < isNotOkString.Length) { // No need to check the rest if this one was not OK break; } List<Connection> matchedUp = SpliceAndConnectionUtils.MatchUp(fromRanges, toRanges); foreach (Connection connection in matchedUp) { Range a = connection.ARange; Range b = connection.BRange; int numUnits = a.High - a.Low + 1; for (int offset = 0; offset < numUnits; offset++) { int aUnit = a.Low + offset; int bUnit = b.Low + offset; if (currentGrid.ContainsKey(aUnit) || currentGrid.ContainsValue(bUnit)) { isNotOkString = string.Format("Duplicate connection found from {0} to {1}.", aUnit, bUnit); // No need to check the rest if this one was not OK break; } else { currentGrid[aUnit] = bUnit; } } } } } catch (Exception ex) { isNotOkString = ex.Message; MessageBox.Show(ex.Message); } // Check the ranges are within the feature's units List<int> checkToUnits = new List<int>(); List<int> checkFromUnits = new List<int>(); // Anything that is in the current grid, we will see if it is available. But if it was deleted, we can ignore // checking its availabilty, because we are about to free it up. Also if it was original, we can ignore it, // since we are reprocessing it. Duplicates ON the grid have already been checked for. // NOTE: We can simplify this to just check original, since any deleted ones were in the original. foreach (int toUnit in currentGrid.Values) { if (!_original.ContainsValue(toUnit)) { checkToUnits.Add(toUnit); } } foreach (int fromUnit in currentGrid.Keys) { if (!_original.ContainsKey(fromUnit)) { checkFromUnits.Add(fromUnit); } } if (PortType.Input == portType) { if (!SpliceAndConnectionUtils.AreRangesAvailable(checkToUnits, device, portType)) { isNotOkString = "Some To units are not in the available ranges for the device."; } else if (!SpliceAndConnectionUtils.AreRangesAvailable(checkFromUnits, cable, isFromEnd)) { isNotOkString = "Some From units are not in the available ranges for the cable."; } } else { if (!SpliceAndConnectionUtils.AreRangesAvailable(checkFromUnits, device, portType)) { isNotOkString = "Some From units are not in the available ranges for the device."; } else if (!SpliceAndConnectionUtils.AreRangesAvailable(checkToUnits, cable, isFromEnd)) { isNotOkString = "Some To units are not in the available ranges for the cable."; } } if (0 == isNotOkString.Length) { // For the deleted ones, if they were added back, don't delete them... List<int> keys = new List<int>(); keys.AddRange(_deleted.Keys); foreach (int key in keys) { if (currentGrid.ContainsKey(key) && currentGrid[key] == _deleted[key]) { // It is added back, so don't delete it _deleted.Remove(key); } } _connectionHelper.BreakConnections(cable, device, _deleted, portType, false); // For the added ones, if they already exist or are not available, don't add them // Since we already know they are in the fiber count range, the only problem would be if they were already // spliced. This would be the case if (1) it was part of the original, (2) has already appeared higher // on the currentGrid, (3) is spliced to something else. (2) is handled when building currentGrid, by checking // if the aUnit or bUnit was already used and (3) is checked in the AreRangesAvailable checks. So now we will // confirm (1)... keys.Clear(); keys.AddRange(currentGrid.Keys); foreach (int key in keys) { if (_original.ContainsKey(key) && _original[key] == currentGrid[key]) { currentGrid.Remove(key); } } _connectionHelper.MakeConnections(cable, device, currentGrid, isFromEnd, portType, false); // These are no longer part of the originals foreach (int deletedKey in _deleted.Keys) { _original.Remove(deletedKey); } // These are now part of the originals foreach (KeyValuePair<int, int> addedPair in currentGrid) { _original[addedPair.Key] = addedPair.Value; } _deleted.Clear(); // The grid is fresh // Set the existing rows as committed data. Less than count-1 lets us avoid the insert row for (int i = 0; i < grdConnections.Rows.Count - 1; i++) { grdConnections.Rows[i].ReadOnly = true; } btnSave.Enabled = false; btnSave.Tag = false; // No edits have been made result = true; } } } catch (Exception ex) { MessageBox.Show("Error: " + ex.ToString()); } if (0 < isNotOkString.Length) { string message = string.Format("{0}\nPlease correct this and try again.", isNotOkString); MessageBox.Show(message, "Connection Editor", MessageBoxButtons.OK, MessageBoxIcon.Error); } return result; }
/// <summary> /// Prompts the user about saving pending edits /// </summary> /// <param name="fromFtWrapper"></param> /// <param name="toFtWrapper"></param> /// <returns>False if the user chooses to cancel what they were doing; True if they choose Yes or No /// (which means they are OK with what they are doing)</returns> private bool IsUserSure(FeatureWrapper fromFtWrapper, FeatureWrapper toFtWrapper) { bool result = true; // Assume they do not want to save and do want to continue DialogResult dialogResult = DialogResult.No; dialogResult = MessageBox.Show("You have unsaved edits. Would you like to save them before closing?", "Connection Editor", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (DialogResult.Cancel == dialogResult) { // The user isn't sure about what they are doing and wants to cancel it result = false; } else if (DialogResult.Yes == dialogResult) { // The user wants to save -- give it a shot bool isSaveOk = SaveChanges(fromFtWrapper, toFtWrapper); if (!isSaveOk) { // They wanted to save but it didn't work. They probably got a message telling them what to fix. Cancel // whatever they were doing so that they have a chance to do so result = false; } } return result; }