예제 #1
0
        /// <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>
        /// 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;
        }