示例#1
0
 /**
  * Adds an undone NullOperation (i.e. has no effects on executing, undoing or redoing) to the
  * Eclipse IOperationHistory to be sure that redoing is possible. This is necessary for the UI
  * Redo possibility being activated.
  */
 protected void simulateUndo() {
   IUndoableOperation auxOp = new NullOperation();
   try {
     auxOp.addContext(context);
     eclipseHistory.execute(auxOp, null, null);
     eclipseHistory.undo(context, null, null);
     if (!eclipseHistory.canRedo(context)) log.error("Simulating Undo failed");
   } catch (ExecutionException e) {
     log.error("Simulating Undo failed");
   }
 }
示例#2
0
        @Override
        public IStatus proceedUndoing(
            final IUndoableOperation operation, IOperationHistory history, IAdaptable info) {

          if (!enabled) return Status.OK_STATUS;

          if (currentActiveEditor == null) {
            log.info("Undo called on an unknown editor");
            return Status.OK_STATUS;
          }

          if (log.isDebugEnabled()) log.debug(opInfo(operation));

          if (operation.getLabel().equals(TYPING_LABEL)) {
            updateCurrentLocalAtomicOperation(null);
            storeCurrentLocalOperation();

            SWTUtils.runSafeSWTSync(
                log,
                new Runnable() {
                  @Override
                  public void run() {
                    log.debug("undoing operation " + operation);
                    undo(currentActiveEditor);

                    if (undoHistory.canRedo(currentActiveEditor)) simulateUndo();
                  }
                });
            return Status.CANCEL_STATUS;
          }
          return Status.OK_STATUS;
        }
  /*
   * Determine whether the operation in question is still valid.
   */
  private IStatus proceedWithOperation(
      final IUndoableOperation operation,
      final IOperationHistory history,
      final IAdaptable uiInfo,
      final int doing) {

    // return immediately if the operation is not relevant
    if (!operation.hasContext(context)) {
      return Status.OK_STATUS;
    }

    // if the operation does not support advanced validation,
    // then we assume it is valid.
    if (doing == EXECUTING) {
      if (!(operation instanceof IAdvancedUndoableOperation2)) {
        return Status.OK_STATUS;
      }
    } else {
      if (!(operation instanceof IAdvancedUndoableOperation)) {
        return Status.OK_STATUS;
      }
    }

    // The next two methods make a number of UI calls, so we wrap the
    // whole thing up in a syncExec.
    final IStatus[] status = new IStatus[1];
    Workbench.getInstance()
        .getDisplay()
        .syncExec(
            new Runnable() {
              public void run() {
                // Compute the undoable or redoable status
                status[0] = computeOperationStatus(operation, history, uiInfo, doing);

                // Report non-OK statuses to the user. In some cases, the user
                // may choose to proceed, and the returned status will be
                // different than what is reported.
                if (!status[0].isOK()) {
                  status[0] = reportAndInterpretStatus(status[0], uiInfo, operation, doing);
                }
              }
            });

    // If the operation is still not OK, inform the history that the
    // operation has changed, since it was previously believed to be valid.
    // We rely here on the ability of an IAdvancedUndoableOperation to
    // correctly report canUndo() and canRedo() once the undoable and
    // redoable status have been computed.
    if (!status[0].isOK()) {
      history.operationChanged(operation);
    }
    return status[0];
  }
示例#4
0
        @Override
        public IStatus proceedRedoing(
            final IUndoableOperation operation, IOperationHistory history, IAdaptable info) {

          if (!enabled) return Status.OK_STATUS;

          if (currentActiveEditor == null) {
            log.info("Redo called on an unknown editor");
            return Status.OK_STATUS;
          }

          if (log.isDebugEnabled()) log.debug(opInfo(operation));

          if (operation.getLabel().equals(TYPING_LABEL)
              || operation.getLabel().equals(NullOperation.LABEL)) {

            updateCurrentLocalAtomicOperation(null);
            storeCurrentLocalOperation();

            SWTUtils.runSafeSWTSync(
                log,
                new Runnable() {
                  @Override
                  public void run() {
                    log.debug("redoing operation " + operation);
                    redo(currentActiveEditor);

                    /*
                     * For reactivating redo an undo has to be simulated, so
                     * the Eclipse history knows, there is something to
                     * redo.
                     */
                    if (undoHistory.canRedo(currentActiveEditor)) simulateUndo();
                  }
                });
            return Status.CANCEL_STATUS;
          }
          return Status.OK_STATUS;
        }
  /*
   * Report a non-OK status to the user
   */
  private IStatus reportAndInterpretStatus(
      IStatus status, IAdaptable uiInfo, IUndoableOperation operation, int doing) {
    // Nothing to report if we are running automated tests.  We will treat
    // warnings as if they were authorized by the user.
    if (AUTOMATED_MODE) {
      if (status.getSeverity() == IStatus.WARNING) {
        return Status.OK_STATUS;
      }
      return status;
    }

    // CANCEL status is assumed to be initiated by the user, so there
    // is nothing to report.
    if (status.getSeverity() == IStatus.CANCEL) {
      return status;
    }

    // Other status severities are reported with a message dialog.
    // First obtain a shell and set up the dialog title.
    boolean createdShell = false;
    IStatus reportedStatus = status;

    Shell shell = getShell(uiInfo);
    if (shell == null) {
      createdShell = true;
      shell = new Shell();
    }

    // Set up the dialog. For non-error statuses, we use a warning dialog
    // that allows the user to proceed or to cancel out of the operation.

    if (!(status.getSeverity() == IStatus.ERROR)) {
      String warning, title;
      switch (doing) {
        case UNDOING:
          warning = WorkbenchMessages.Operations_proceedWithNonOKUndoStatus;
          if (status.getSeverity() == IStatus.INFO) {
            title = WorkbenchMessages.Operations_undoInfo;
          } else {
            title = WorkbenchMessages.Operations_undoWarning;
          }
          break;
        case REDOING:
          warning = WorkbenchMessages.Operations_proceedWithNonOKRedoStatus;
          if (status.getSeverity() == IStatus.INFO) {
            title = WorkbenchMessages.Operations_redoInfo;
          } else {
            title = WorkbenchMessages.Operations_redoWarning;
          }
          break;
        default: // EXECUTING
          warning = WorkbenchMessages.Operations_proceedWithNonOKExecuteStatus;
          if (status.getSeverity() == IStatus.INFO) {
            title = WorkbenchMessages.Operations_executeInfo;
          } else {
            title = WorkbenchMessages.Operations_executeWarning;
          }
          break;
      }

      String message = NLS.bind(warning, new Object[] {status.getMessage(), operation.getLabel()});
      String[] buttons = new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL};
      MessageDialog dialog =
          new MessageDialog(shell, title, null, message, MessageDialog.WARNING, buttons, 0);
      int dialogAnswer = dialog.open();
      // The user has been given the specific status and has chosen
      // to proceed or to cancel. The user choice determines what
      // the status should be at this point, OK or CANCEL.
      if (dialogAnswer == Window.OK) {
        reportedStatus = Status.OK_STATUS;
      } else {
        reportedStatus = Status.CANCEL_STATUS;
      }
    } else {
      String title, stopped;
      switch (doing) {
        case UNDOING:
          title = WorkbenchMessages.Operations_undoProblem;
          stopped = WorkbenchMessages.Operations_stoppedOnUndoErrorStatus;
          break;
        case REDOING:
          title = WorkbenchMessages.Operations_redoProblem;
          stopped = WorkbenchMessages.Operations_stoppedOnRedoErrorStatus;
          break;
        default: // EXECUTING
          title = WorkbenchMessages.Operations_executeProblem;
          stopped = WorkbenchMessages.Operations_stoppedOnExecuteErrorStatus;

          break;
      }

      // It is an error condition. The user has no choice to proceed, so
      // we only report what has gone on. We use a warning icon instead of
      // an error icon since there has not yet been a failure.

      String message = NLS.bind(stopped, status.getMessage(), operation.getLabel());

      MessageDialog dialog =
          new MessageDialog(
              shell,
              title,
              null,
              message,
              MessageDialog.WARNING,
              new String[] {IDialogConstants.OK_LABEL},
              0); // ok
      dialog.open();
    }

    if (createdShell) {
      shell.dispose();
    }

    return reportedStatus;
  }
  /** @see IActionDelegate#run(IAction) */
  public void run(IAction action) {
    try {
      final Element selectedElement = getSelectedElement();

      IUndoableOperation operation =
          new AbstractEMFOperation(editingDomain, "Create Nested Subclass") {
            @Override
            protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) {
              Property property = null;

              if (selectedElement instanceof Association) {
                Association association = (Association) selectedElement;
                property = UMLUtil.getNavigableEnd(association);
              } else if (selectedElement instanceof Property) {
                property = (Property) selectedElement;
              }

              if (property == null || !(property.getType() instanceof Class)) {
                return Status.CANCEL_STATUS;
              }

              Class baseClass = (Class) property.getType();

              // prompt for new class name
              String className = null;
              InputDialog inputDialog =
                  new InputDialog(
                      activePart.getSite().getShell(),
                      "Nested Class",
                      "Enter class name",
                      baseClass.getName(),
                      null);
              if (inputDialog.open() == Window.OK) {
                className = inputDialog.getValue();
              }
              if (className == null || className.length() == 0) {
                return Status.CANCEL_STATUS;
              }

              Class newClass = UMLFactory.eINSTANCE.createClass();
              property.getClass_().getNestedClassifiers().add(newClass);
              newClass.setName(className);
              property.setType(newClass);

              // create new generalization
              newClass.createGeneralization(baseClass);

              // prompt for selection of redefined properties
              // TODO customize dialog title and prompt
              SubclassHandler subclassHandler =
                  new SubclassHandler(activePart.getSite().getShell(), newClass);
              subclassHandler.openSubclassDialog();

              // TODO this does not select in CommonNavigator. maybe need a refresh first?
              if (activePart instanceof ISetSelectionTarget) {
                ((ISetSelectionTarget) activePart).selectReveal(new StructuredSelection(newClass));
              }

              return Status.OK_STATUS;
            }
          };

      try {
        IWorkspaceCommandStack commandStack =
            (IWorkspaceCommandStack) editingDomain.getCommandStack();
        operation.addContext(commandStack.getDefaultUndoContext());
        commandStack.getOperationHistory().execute(operation, new NullProgressMonitor(), null);

      } catch (ExecutionException ee) {
        Logger.logException(ee);
      }

    } catch (Exception e) {
      throw new RuntimeException(e.getCause());
    }
  }
示例#7
0
  @Override
  public IUndoableOperation commit() {
    final IUndoableOperation updateVisualOperation = super.commit();
    if (updateVisualOperation == null) {
      return null;
    }

    // commit changes to model
    final FXGeometricShapePart host = getHost();
    final FXGeometricShape hostContent = host.getContent();

    // determine transformation
    @SuppressWarnings("serial")
    Provider<Affine> affineProvider =
        host.getAdapter(
            AdapterKey.<Provider<? extends Affine>>get(
                new TypeToken<Provider<? extends Affine>>() {},
                FXTransformPolicy.TRANSFORMATION_PROVIDER_ROLE));
    AffineTransform tx = JavaFX2Geometry.toAffineTransform(affineProvider.get());
    final AffineTransform oldTransform = hostContent.getTransform();
    final AffineTransform newTransform =
        new AffineTransform(
            tx.getM00(),
            tx.getM10(),
            tx.getM01(),
            tx.getM11(),
            tx.getTranslateX(),
            tx.getTranslateY());

    // create operation to write the changes to the model
    final IUndoableOperation updateModelOperation =
        new AbstractOperation("Update Model") {

          @Override
          public IStatus execute(IProgressMonitor monitor, IAdaptable info)
              throws ExecutionException {
            hostContent.setTransform(newTransform);
            return Status.OK_STATUS;
          }

          @Override
          public IStatus redo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
            return execute(monitor, info);
          }

          @Override
          public IStatus undo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
            hostContent.setTransform(oldTransform);
            return Status.OK_STATUS;
          }
        };
    // compose operations
    IUndoableOperation compositeOperation =
        new ForwardUndoCompositeOperation(updateVisualOperation.getLabel()) {
          {
            add(updateVisualOperation);
            add(updateModelOperation);
          }
        };

    return compositeOperation;
  }
示例#8
0
 protected String opInfo(IUndoableOperation operation) {
   return ("new " + operation.getLabel() + ": " + operation);
 }