示例#1
0
 /// <summary>
 /// Executes a procedure in an edit operation
 /// </summary>
 /// <param name="workspace">The workspace in which the operation is executed</param>
 /// <param name="procedure">The operation.</param>
 /// <param name="state">The state.</param>
 /// <param name="description">The description for the edit operation.</param>
 /// <returns><c>true</c> if the operation succeeded, <c>false</c> if it was aborted.</returns>
 public bool Execute(IWorkspace workspace, Action procedure,
                     EditStateInfo state, string description)
 {
     return(Execute(workspace,
                    delegate { procedure(); },
                    state, description, null));
 }
示例#2
0
        /// <summary>
        /// Executes a procedure in an edit operation
        /// </summary>
        /// <param name="workspace">The workspace in which the operation is executed</param>
        /// <param name="procedure">The operation.</param>
        /// <param name="state">The state.</param>
        /// <param name="description">The description for the edit operation.</param>
        /// <param name="trackCancel">The cancel tracker (optional).</param>
        /// <returns>
        ///     <c>true</c> if the operation succeeded, <c>false</c> if it was aborted.
        /// </returns>
        public bool Execute(IWorkspace workspace, Action <ITrackCancel> procedure,
                            EditStateInfo state, string description,
                            ITrackCancel trackCancel)
        {
            Assert.ArgumentNotNull(workspace, nameof(workspace));
            Assert.ArgumentNotNull(procedure, nameof(procedure));
            Assert.ArgumentNotNullOrEmpty(description, nameof(description));

            if (trackCancel != null)
            {
                Assert.True(trackCancel.Continue(), "Cancel tracker already cancelled");
            }

            using (EditWorkspace(workspace))
            {
                var editWs  = (IWorkspaceEdit)workspace;
                var editWs2 = workspace as IWorkspaceEdit2;                 // not implemented for shapefiles

                bool isBeingEdited     = editWs.IsBeingEdited();
                bool isInEditOperation = (editWs2 != null && editWs2.IsInEditOperation);

                if ((state & EditStateInfo.MustNotBeEditing) != 0)
                {
                    Assert.False(isBeingEdited, "Edit Session already open");
                }

                if ((state & EditStateInfo.MustBeEditing) != 0)
                {
                    Assert.True(isBeingEdited, "Edit Session not open");
                }

                if ((state & EditStateInfo.MustNotBeInOperation) != 0)
                {
                    if (isInEditOperation)
                    {
                        AbortEditOperation();
                        _msg.Warn("Rolled back unexpected existing edit operation");
                    }

                    isInEditOperation = false;
                }

                if ((state & EditStateInfo.MustBeInOperation) != 0)
                {
                    Assert.True(isInEditOperation, "Edit Session not in Operation");
                }

                _aborted = false;

                IWorkspaceEditEvents_Event workspaceEditEvents = null;

                try
                {
                    #region check reset current state

                    if (isInEditOperation)
                    {
                        if ((state & EditStateInfo.AbortExistingOperation) != 0)
                        {
                            Assert.True(
                                (state & EditStateInfo.StopExistingOperation) == 0,
                                "Cannot specify both " +
                                EditStateInfo.AbortExistingOperation + " and " +
                                EditStateInfo.StopExistingOperation);
                            AbortEditOperation();
                            isInEditOperation = false;
                        }
                        else if ((state & EditStateInfo.StopExistingOperation) != 0)
                        {
                            StopEditOperation(description);
                            isInEditOperation = false;
                        }
                    }

                    if (isBeingEdited)
                    {
                        if ((state & EditStateInfo.AbortExistingEditing) != 0)
                        {
                            Assert.True((state & EditStateInfo.StopExistingEditing) == 0,
                                        "Cannot specify both " +
                                        EditStateInfo.AbortExistingEditing + " and " +
                                        EditStateInfo.StopExistingEditing);

                            StopEditing(false);
                            isBeingEdited = false;
                        }
                        else if ((state & EditStateInfo.StopExistingEditing) != 0)
                        {
                            StopEditing(true);
                            isBeingEdited = false;
                        }
                    }

                    #endregion

                    if (!isBeingEdited)
                    {
                        StartEditing();
                    }

                    if (!isInEditOperation && (state & EditStateInfo.DontStartOperation) == 0)
                    {
                        StartEditOperation();
                    }

                    // this may fail (COM object that has been separated from its underlying RCW cannot be used)
                    workspaceEditEvents = (IWorkspaceEditEvents_Event)workspace;
                    workspaceEditEvents.OnAbortEditOperation += editEvents_OnAbortEditOperation;

                    procedure(trackCancel);

                    if (trackCancel != null && !trackCancel.Continue())
                    {
                        _msg.WarnFormat("Operation cancelled: {0}", description);

                        // cancel was called in procedure
                        if (!_aborted)
                        {
                            // The operation is not yet aborted. Abort it now.
                            AbortEditOperation();
                        }
                    }

                    if (!_aborted &&
                        (!isInEditOperation &&
                         (state & EditStateInfo.KeepOperation) == 0) ||
                        (state & EditStateInfo.StopOperation) != 0)
                    {
                        // if the edit operation violates rule engine rules, the edit operation won't succeed. However
                        // no exception is reported when calling StopEditOperation --> the OnAbort handler is mandatory
                        // to detect this situation.
                        StopEditOperation(description);
                    }

                    if ((!isBeingEdited &&
                         (state & EditStateInfo.KeepEditing) == 0) ||
                        (state & EditStateInfo.StopEditing) != 0)
                    {
                        StopEditing(true);
                    }

                    return(!_aborted);
                }
                catch (Exception ex)
                {
                    try                     // Clean up
                    {
                        var    comEx   = ex as COMException;
                        string message =
                            comEx == null
                                                                ? string.Format("Error executing operation: {0} ({1})",
                                                                                description, ex.Message)
                                                                : string.Format(
                                "Error executing operation: {0} ({1}; Error Code: {2})",
                                description, comEx.Message, comEx.ErrorCode);

                        _msg.Debug(message);

                        if (!isInEditOperation)
                        {
                            // if the error occurred in StopEditOperation(), then
                            // that edit operation might already be aborted -> check
                            if (editWs2 != null && editWs2.IsInEditOperation)
                            {
                                AbortEditOperation();
                            }
                        }

                        if (!isBeingEdited)
                        {
                            StopEditing(false);
                        }
                    }
                    catch (Exception e2)
                    {
                        // exception intentionally suppressed.
                        _msg.Error("Error cleaning up after failed gdb function", e2);
                    }

                    throw;
                }
                finally
                {
                    try
                    {
                        if (workspaceEditEvents != null)
                        {
                            workspaceEditEvents.OnAbortEditOperation -=
                                editEvents_OnAbortEditOperation;
                        }
                    }
                    catch (AccessViolationException e)
                    {
                        // exception intentionally suppressed.
                        _msg.Warn("Error unregistering event handler", e);
                    }
                }
            }
        }