Package org.eclipse.php.internal.ui.compare

Source Code of org.eclipse.php.internal.ui.compare.MergeSourceViewer

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.ui.compare;

import java.util.*;

import org.eclipse.compare.ICompareContainer;
import org.eclipse.compare.internal.MergeViewerAction;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.jface.action.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.source.*;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.FindReplaceAction;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;

/**
* Extends the JFace SourceViewer with some convenience methods.
*/
public class MergeSourceViewer extends StructuredTextViewer implements
    ISelectionChangedListener, ITextListener, IMenuListener,
    IOperationHistoryListener {

  public static final String UNDO_ID = "undo"; //$NON-NLS-1$
  public static final String REDO_ID = "redo"; //$NON-NLS-1$
  public static final String CUT_ID = "cut"; //$NON-NLS-1$
  public static final String COPY_ID = "copy"; //$NON-NLS-1$
  public static final String PASTE_ID = "paste"; //$NON-NLS-1$
  public static final String DELETE_ID = "delete"; //$NON-NLS-1$
  public static final String SELECT_ALL_ID = "selectAll"; //$NON-NLS-1$
  public static final String SAVE_ID = "save"; //$NON-NLS-1$
  public static final String FIND_ID = "find"; //$NON-NLS-1$

  class TextOperationAction extends MergeViewerAction {

    private int fOperationCode;

    TextOperationAction(int operationCode, boolean mutable,
        boolean selection, boolean content) {
      this(operationCode, null, mutable, selection, content);

    }

    public TextOperationAction(int operationCode,
        String actionDefinitionId, boolean mutable, boolean selection,
        boolean content) {
      super(mutable, selection, content);
      if (actionDefinitionId != null)
        setActionDefinitionId(actionDefinitionId);
      fOperationCode = operationCode;
      update();
    }

    public void run() {
      if (isEnabled())
        doOperation(fOperationCode);
    }

    public boolean isEnabled() {
      return fOperationCode != -1 && canDoOperation(fOperationCode);
    }

    public void update() {
      this.setEnabled(isEnabled());
    }
  }

  private ResourceBundle fResourceBundle;
  private Position fRegion;
  private boolean fEnabled = true;
  private HashMap fActions = new HashMap();
  private IDocument fRememberedDocument;

  private boolean fAddSaveAction = true;
  private boolean isConfigured = false;

  // line number ruler support
  private IPropertyChangeListener fPreferenceChangeListener;
  private boolean fShowLineNumber = false;
  private LineNumberRulerColumn fLineNumberColumn;
  private List textActions = new ArrayList();

  public MergeSourceViewer(Composite parent, int style,
      ResourceBundle bundle, ICompareContainer container) {
    super(parent, new CompositeRuler(), null, false, style | SWT.H_SCROLL
        | SWT.V_SCROLL);

    fResourceBundle = bundle;

    MenuManager menu = new MenuManager();
    menu.setRemoveAllWhenShown(true);
    menu.addMenuListener(this);
    StyledText te = getTextWidget();
    te.setMenu(menu.createContextMenu(te));
    container.registerContextMenu(menu, this);

    // for listening to editor show/hide line number preference value
    fPreferenceChangeListener = new IPropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent event) {
        MergeSourceViewer.this.handlePropertyChangeEvent(event);
      }
    };
    EditorsUI.getPreferenceStore().addPropertyChangeListener(
        fPreferenceChangeListener);
    fShowLineNumber = EditorsUI
        .getPreferenceStore()
        .getBoolean(
            AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER);
    if (fShowLineNumber) {
      updateLineNumberRuler();
    }

    IOperationHistory history = getHistory();
    if (history != null)
      history.addOperationHistoryListener(this);
  }

  public void rememberDocument(IDocument doc) {
    // if (doc != null && fRememberedDocument != null) {
    //      System.err.println("MergeSourceViewer.rememberDocument: fRememberedDocument != null: shouldn't happen"); //$NON-NLS-1$
    // }
    fRememberedDocument = doc;
  }

  public IDocument getRememberedDocument() {
    return fRememberedDocument;
  }

  public void hideSaveAction() {
    fAddSaveAction = false;
  }

  public void setFont(Font font) {
    StyledText te = getTextWidget();
    if (te != null)
      te.setFont(font);
    if (fLineNumberColumn != null) {
      fLineNumberColumn.setFont(font);
      layoutViewer();
    }
  }

  public void setBackgroundColor(Color color) {
    StyledText te = getTextWidget();
    if (te != null)
      te.setBackground(color);
    if (fLineNumberColumn != null)
      fLineNumberColumn.setBackground(color);
  }

  public void setEnabled(boolean enabled) {
    if (enabled != fEnabled) {
      fEnabled = enabled;
      StyledText c = getTextWidget();
      if (c != null) {
        c.setEnabled(enabled);
        Display d = c.getDisplay();
        c.setBackground(enabled ? d
            .getSystemColor(SWT.COLOR_LIST_BACKGROUND) : null);
      }
    }
  }

  public boolean getEnabled() {
    return fEnabled;
  }

  public void setRegion(Position region) {
    fRegion = region;
  }

  public Position getRegion() {
    return fRegion;
  }

  public boolean isControlOkToUse() {
    StyledText t = getTextWidget();
    return t != null && !t.isDisposed();
  }

  public void setSelection(Position position) {
    if (position != null)
      setSelectedRange(position.getOffset(), position.getLength());
  }

  public void setLineBackground(Position position, Color c) {
    StyledText t = getTextWidget();
    if (t != null && !t.isDisposed()) {
      Point region = new Point(0, 0);
      getLineRange(position, region);

      region.x -= getDocumentRegionOffset();

      try {
        t.setLineBackground(region.x, region.y, c);
      } catch (IllegalArgumentException ex) {
        // silently ignored
      }
    }
  }

  public void resetLineBackground() {
    StyledText t = getTextWidget();
    if (t != null && !t.isDisposed()) {
      int lines = getLineCount();
      t.setLineBackground(0, lines, null);
    }
  }

  /*
   * Returns number of lines in document region.
   */
  public int getLineCount() {
    IRegion region = getVisibleRegion();

    int length = region.getLength();
    if (length == 0)
      return 0;

    IDocument doc = getDocument();
    int startLine = 0;
    int endLine = 0;

    int start = region.getOffset();
    try {
      startLine = doc.getLineOfOffset(start);
    } catch (BadLocationException ex) {
      // silently ignored
    }
    try {
      endLine = doc.getLineOfOffset(start + length);
    } catch (BadLocationException ex) {
      // silently ignored
    }

    return endLine - startLine + 1;
  }

  public int getViewportLines() {
    StyledText te = getTextWidget();
    Rectangle clArea = te.getClientArea();
    if (!clArea.isEmpty())
      return clArea.height / te.getLineHeight();
    return 0;
  }

  public int getViewportHeight() {
    StyledText te = getTextWidget();
    Rectangle clArea = te.getClientArea();
    if (!clArea.isEmpty())
      return clArea.height;
    return 0;
  }

  /*
   * Returns lines
   */
  public int getDocumentRegionOffset() {
    int start = getVisibleRegion().getOffset();
    IDocument doc = getDocument();
    if (doc != null) {
      try {
        return doc.getLineOfOffset(start);
      } catch (BadLocationException ex) {
        // silently ignored
      }
    }
    return 0;
  }

  public int getVerticalScrollOffset() {
    StyledText st = getTextWidget();
    int lineHeight = st.getLineHeight();
    return getTopInset()
        - ((getDocumentRegionOffset() * lineHeight) + st.getTopPixel());
  }

  /*
   * Returns the start line and the number of lines which correspond to the
   * given position. Starting line number is 0 based.
   */
  public Point getLineRange(Position p, Point region) {

    IDocument doc = getDocument();

    if (p == null || doc == null) {
      region.x = 0;
      region.y = 0;
      return region;
    }

    int start = p.getOffset();
    int length = p.getLength();

    int startLine = 0;
    try {
      startLine = doc.getLineOfOffset(start);
    } catch (BadLocationException e) {
      // silently ignored
    }

    int lineCount = 0;

    if (length == 0) {
      // // if range length is 0 and if range starts a new line
      // try {
      // if (start == doc.getLineStartOffset(startLine)) {
      // lines--;
      // }
      // } catch (BadLocationException e) {
      // lines--;
      // }

    } else {
      int endLine = 0;
      try {
        endLine = doc.getLineOfOffset(start + length - 1); // why -1?
      } catch (BadLocationException e) {
        // silently ignored
      }
      lineCount = endLine - startLine + 1;
    }

    region.x = startLine;
    region.y = lineCount;
    return region;
  }

  /*
   * Scroll TextPart to the given line.
   */
  public void vscroll(int line) {

    int srcViewSize = getLineCount();
    int srcExtentSize = getViewportLines();

    if (srcViewSize > srcExtentSize) {

      if (line < 0)
        line = 0;

      int cp = getTopIndex();
      if (cp != line)
        setTopIndex(line + getDocumentRegionOffset());
    }
  }

  public void addAction(String actionId, MergeViewerAction action) {
    fActions.put(actionId, action);
  }

  public IAction getAction(String actionId) {
    IAction action = (IAction) fActions.get(actionId);
    if (action == null) {
      action = createAction(actionId);
      if (action == null)
        return null;
      if (action instanceof MergeViewerAction) {
        MergeViewerAction mva = (MergeViewerAction) action;
        if (mva.isContentDependent())
          addTextListener(this);
        if (mva.isSelectionDependent())
          addSelectionChangedListener(this);

        Utilities.initAction(action, fResourceBundle,
            "action." + actionId + "."); //$NON-NLS-1$ //$NON-NLS-2$
      }
      addAction(actionId, action);

    }
    if (action instanceof MergeViewerAction) {
      MergeViewerAction mva = (MergeViewerAction) action;
      if (mva.isEditableDependent() && !isEditable())
        return null;
    }
    return action;
  }

  protected IAction createAction(String actionId) {
    if (UNDO_ID.equals(actionId))
      return new TextOperationAction(UNDO,
          "org.eclipse.ui.edit.undo", true, false, true); //$NON-NLS-1$
    if (REDO_ID.equals(actionId))
      return new TextOperationAction(REDO,
          "org.eclipse.ui.edit.redo", true, false, true); //$NON-NLS-1$
    if (CUT_ID.equals(actionId))
      return new TextOperationAction(CUT,
          "org.eclipse.ui.edit.cut", true, true, false); //$NON-NLS-1$
    if (COPY_ID.equals(actionId))
      return new TextOperationAction(COPY,
          "org.eclipse.ui.edit.copy", false, true, false); //$NON-NLS-1$
    if (PASTE_ID.equals(actionId))
      return new TextOperationAction(PASTE,
          "org.eclipse.ui.edit.paste", true, false, false); //$NON-NLS-1$
    if (DELETE_ID.equals(actionId))
      return new TextOperationAction(DELETE,
          "org.eclipse.ui.edit.delete", true, false, false); //$NON-NLS-1$
    if (SELECT_ALL_ID.equals(actionId))
      return new TextOperationAction(SELECT_ALL,
          "org.eclipse.ui.edit.selectAll", false, false, false); //$NON-NLS-1$
    return null;
  }

  public void selectionChanged(SelectionChangedEvent event) {
    Iterator e = fActions.values().iterator();
    while (e.hasNext()) {
      Object next = e.next();
      if (next instanceof MergeViewerAction) {
        MergeViewerAction action = (MergeViewerAction) next;
        if (action.isSelectionDependent())
          action.update();
      }
    }
  }

  public void textChanged(TextEvent event) {
    updateContentDependantActions();
  }

  void updateContentDependantActions() {
    Iterator e = fActions.values().iterator();
    while (e.hasNext()) {
      Object next = e.next();
      if (next instanceof MergeViewerAction) {
        MergeViewerAction action = (MergeViewerAction) next;
        if (action.isContentDependent())
          action.update();
      }
    }
  }

  /*
   * Allows the viewer to add menus and/or tools to the context menu.
   */
  public void menuAboutToShow(IMenuManager menu) {

    menu.add(new Separator("undo")); //$NON-NLS-1$
    addMenu(menu, UNDO_ID);
    addMenu(menu, REDO_ID);
    menu.add(new GroupMarker("save")); //$NON-NLS-1$
    if (fAddSaveAction)
      addMenu(menu, SAVE_ID);
    menu.add(new Separator("file")); //$NON-NLS-1$

    menu.add(new Separator("ccp")); //$NON-NLS-1$
    addMenu(menu, CUT_ID);
    addMenu(menu, COPY_ID);
    addMenu(menu, PASTE_ID);
    addMenu(menu, DELETE_ID);
    addMenu(menu, SELECT_ALL_ID);

    menu.add(new Separator("edit")); //$NON-NLS-1$
    menu.add(new Separator("find")); //$NON-NLS-1$
    addMenu(menu, FIND_ID);

    menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

    menu.add(new Separator("text")); //$NON-NLS-1$
    for (Iterator iterator = textActions.iterator(); iterator.hasNext();) {
      IAction action = (IAction) iterator.next();
      menu.add(action);
    }

    menu.add(new Separator("rest")); //$NON-NLS-1$

    // update all actions
    // to get undo redo right
    updateActions();
  }

  private void addMenu(IMenuManager menu, String actionId) {
    IAction action = getAction(actionId);
    if (action != null)
      menu.add(action);
  }

  protected void handleDispose() {

    removeTextListener(this);
    removeSelectionChangedListener(this);
    EditorsUI.getPreferenceStore().removePropertyChangeListener(
        fPreferenceChangeListener);

    IOperationHistory history = getHistory();
    if (history != null)
      history.removeOperationHistoryListener(this);

    super.handleDispose();
  }

  /**
   * update all actions independent of their type
   *
   */
  public void updateActions() {
    Iterator e = fActions.values().iterator();
    while (e.hasNext()) {
      Object next = e.next();
      if (next instanceof MergeViewerAction) {
        MergeViewerAction action = (MergeViewerAction) next;
        action.update();
      }
      if (next instanceof FindReplaceAction) {
        FindReplaceAction action = (FindReplaceAction) next;
        action.update();
      }
    }
  }

  public void configure(SourceViewerConfiguration configuration) {
    if (isConfigured)
      unconfigure();
    isConfigured = true;
    super.configure(configuration);
  }

  /**
   * specific implementation to support a vertical ruler
   *
   * @param x
   * @param y
   * @param width
   * @param height
   */
  public void setBounds(int x, int y, int width, int height) {
    if (getControl() instanceof Composite) {
      ((Composite) getControl()).setBounds(x, y, width, height);
    } else {
      getTextWidget().setBounds(x, y, width, height);
    }
  }

  /**
   * handle show/hide line numbers from editor preferences
   *
   * @param event
   */
  protected void handlePropertyChangeEvent(PropertyChangeEvent event) {

    String key = event.getProperty();

    if (key
        .equals(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER)) {
      boolean b = EditorsUI
          .getPreferenceStore()
          .getBoolean(
              AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER);
      if (b != fShowLineNumber) {
        toggleLineNumberRuler();
      }
    } else if (key
        .equals(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR)) {
      updateLineNumberColumnPresentation(true);
    }
  }

  /**
   * Hides or shows line number ruler column based of preference setting
   */
  private void updateLineNumberRuler() {
    IVerticalRuler v = getVerticalRuler();
    if (v != null && v instanceof CompositeRuler) {
      CompositeRuler c = (CompositeRuler) v;

      if (!fShowLineNumber) {
        if (fLineNumberColumn != null) {
          c.removeDecorator(fLineNumberColumn);
        }
      } else {
        if (fLineNumberColumn == null) {
          fLineNumberColumn = new LineNumberRulerColumn();
          updateLineNumberColumnPresentation(false);
        }
        c.addDecorator(0, fLineNumberColumn);
      }
    }
  }

  private void updateLineNumberColumnPresentation(boolean refresh) {
    if (fLineNumberColumn == null)
      return;
    RGB rgb = getColorFromStore(
        EditorsUI.getPreferenceStore(),
        AbstractDecoratedTextEditorPreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR);
    if (rgb == null)
      rgb = new RGB(0, 0, 0);
    ISharedTextColors sharedColors = getSharedColors();
    fLineNumberColumn.setForeground(sharedColors.getColor(rgb));
    if (refresh) {
      fLineNumberColumn.redraw();
    }
  }

  private void layoutViewer() {
    Control parent = getControl();
    if (parent instanceof Composite && !parent.isDisposed())
      ((Composite) parent).layout(true);
  }

  private ISharedTextColors getSharedColors() {
    return EditorsUI.getSharedTextColors();
  }

  private RGB getColorFromStore(IPreferenceStore store, String key) {
    RGB rgb = null;
    if (store.contains(key)) {
      if (store.isDefault(key))
        rgb = PreferenceConverter.getDefaultColor(store, key);
      else
        rgb = PreferenceConverter.getColor(store, key);
    }
    return rgb;
  }

  /**
   * Toggles line number ruler column.
   */
  private void toggleLineNumberRuler() {
    fShowLineNumber = !fShowLineNumber;

    updateLineNumberRuler();
  }

  public void addTextAction(IAction textEditorPropertyAction) {
    textActions.add(textEditorPropertyAction);
  }

  public void addAction(String id, IAction action) {
    fActions.put(id, action);
  }

  private IOperationHistory getHistory() {
    if (PlatformUI.getWorkbench() == null) {
      return null;
    }
    return PlatformUI.getWorkbench().getOperationSupport()
        .getOperationHistory();
  }

  public void historyNotification(OperationHistoryEvent event) {
    // This method updates the enablement of all content operations
    // when the undo history changes. It could be localized to UNDO and
    // REDO.
    IUndoContext context = getUndoContext();
    if (context != null && event.getOperation().hasContext(context)) {
      Display.getDefault().asyncExec(new Runnable() {
        public void run() {
          updateContentDependantActions();
        }
      });
    }
  }

  private IUndoContext getUndoContext() {
    IUndoManager undoManager = getUndoManager();
    if (undoManager instanceof IUndoManagerExtension)
      return ((IUndoManagerExtension) undoManager).getUndoContext();
    return null;
  }
}
TOP

Related Classes of org.eclipse.php.internal.ui.compare.MergeSourceViewer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.