SurroundWithTemplateMenuAction.java :  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » ui » actions » Java Open Source

Java Open Source » IDE Eclipse » jdt 
jdt » org » eclipse » jdt » internal » ui » actions » SurroundWithTemplateMenuAction.java
/*******************************************************************************
 * Copyright (c) 2000, 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
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.actions;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IEditingSupport;
import org.eclipse.jface.text.IEditingSupportRegistry;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;

import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import org.eclipse.ui.dialogs.PreferencesUtil;

import org.eclipse.jdt.core.ICompilationUnit;

import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
import org.eclipse.jdt.ui.actions.SurroundWithTryCatchAction;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
import org.eclipse.jdt.internal.ui.text.correction.QuickTemplateProcessor;

public class SurroundWithTemplateMenuAction implements IWorkbenchWindowPulldownDelegate2 {

  //TODO make api
  public static final String SURROUND_WITH_QUICK_MENU_ACTION_ID= "org.eclipse.jdt.ui.edit.text.java.surround.with.quickMenu";  //$NON-NLS-1$

  private static final String JAVA_TEMPLATE_PREFERENCE_PAGE_ID= "org.eclipse.jdt.ui.preferences.JavaTemplatePreferencePage"; //$NON-NLS-1$

  private static final String TEMPLATE_GROUP= "templateGroup"; //$NON-NLS-1$

  private static final String CONFIG_GROUP= "configGroup"; //$NON-NLS-1$

  private static class ConfigureTemplatesAction extends Action {

    public ConfigureTemplatesAction() {
      super(ActionMessages.SurroundWithTemplateMenuAction_ConfigureTemplatesActionName);
    }

    /**
     * {@inheritDoc}
     */
    public void run() {
      PreferencesUtil.createPreferenceDialogOn(getShell(), JAVA_TEMPLATE_PREFERENCE_PAGE_ID, new String[] {JAVA_TEMPLATE_PREFERENCE_PAGE_ID}, null).open();
    }

    private Shell getShell() {
      return JavaPlugin.getActiveWorkbenchWindow().getShell();
    }
  }

  private static Action NONE_APPLICABLE_ACTION= new Action(ActionMessages.SurroundWithTemplateMenuAction_NoneApplicable) {
    public void run() {
      //Do nothing
    }
    public boolean isEnabled() {
      return false;
    }
  };

  private Menu fMenu;
  private IPartService fPartService;
  private IPartListener fPartListener= new IPartListener() {

    public void partActivated(IWorkbenchPart part) {
    }

    public void partBroughtToTop(IWorkbenchPart part) {
    }

    public void partClosed(IWorkbenchPart part) {
    }

    public void partDeactivated(IWorkbenchPart part) {
      disposeMenuItems();
    }

    public void partOpened(IWorkbenchPart part) {
    }

  };

  protected void disposeMenuItems() {
    if (fMenu == null || fMenu.isDisposed()) {
      return;
    }
    MenuItem[] items = fMenu.getItems();
    for (int i=0; i < items.length; i++) {
      MenuItem menuItem= items[i];
      if (!menuItem.isDisposed()) {
        menuItem.dispose();
      }
    }
  }

  /**
   * {@inheritDoc}
   */
  public Menu getMenu(Menu parent) {
    setMenu(new Menu(parent));
    fillMenu(fMenu);
    initMenu();
    return fMenu;
  }

  /**
   * {@inheritDoc}
   */
  public Menu getMenu(Control parent) {
    setMenu(new Menu(parent));
    fillMenu(fMenu);
    initMenu();
    return fMenu;
  }

  public static void fillMenu(IMenuManager menu, CompilationUnitEditor editor, SurroundWithTryCatchAction surroundWithTryCatchAction) {
    IAction[] actions= getTemplateActions(editor);

    surroundWithTryCatchAction.update(editor.getSelectionProvider().getSelection());
    boolean addSurroundWithAction= surroundWithTryCatchAction.isEnabled() && !isInJavadoc(editor);

    if ((actions == null || actions.length == 0) && !addSurroundWithAction) {
      menu.add(NONE_APPLICABLE_ACTION);
    } else {
      if (addSurroundWithAction)
        menu.add(surroundWithTryCatchAction);

      menu.add(new Separator(TEMPLATE_GROUP));
      for (int i= 0; actions != null && i < actions.length; i++)
        menu.add(actions[i]);

    }

    menu.add(new Separator(CONFIG_GROUP));
    menu.add(new ConfigureTemplatesAction());
  }

  /**
   * {@inheritDoc}
   */
  public void dispose() {
    if (fPartService != null) {
      fPartService.removePartListener(fPartListener);
      fPartService= null;
    }
    setMenu(null);
  }

  /**
   * {@inheritDoc}
   */
  public void init(IWorkbenchWindow window) {
    if (fPartService != null) {
      fPartService.removePartListener(fPartListener);
      fPartService= null;
    }

    if (window != null) {
      IPartService partService= window.getPartService();
      if (partService != null) {
        fPartService= partService;
        partService.addPartListener(fPartListener);
      }
    }
  }

  /**
   * {@inheritDoc}
   */
  public void run(IAction action) {
    IWorkbenchPart activePart= JavaPlugin.getActivePage().getActivePart();
    if (!(activePart instanceof CompilationUnitEditor))
      return;

    final CompilationUnitEditor editor= (CompilationUnitEditor)activePart;

    new JDTQuickMenuCreator(editor) {
      protected void fillMenu(IMenuManager menu) {
        SurroundWithTryCatchAction surroundWithTryCatch= createSurroundWithTryCatchAction(editor);
        SurroundWithTemplateMenuAction.fillMenu(menu, editor, surroundWithTryCatch);
      }
    }.createMenu();
  }

  /**
   * {@inheritDoc}
   */
  public void selectionChanged(IAction action, ISelection selection) {
    // Default do nothing
  }

  /**
   * The menu to show in the workbench menu
   * @param menu the menu to fill entries into it
   */
  protected void fillMenu(Menu menu) {

    IWorkbenchPart activePart= JavaPlugin.getActivePage().getActivePart();
    if (!(activePart instanceof CompilationUnitEditor)) {
      ActionContributionItem item= new ActionContributionItem(NONE_APPLICABLE_ACTION);
      item.fill(menu, -1);
      return;
    }

    CompilationUnitEditor editor= (CompilationUnitEditor)activePart;
    if (editor.isBreadcrumbActive()) {
      ActionContributionItem item= new ActionContributionItem(NONE_APPLICABLE_ACTION);
      item.fill(menu, -1);
      return;
    }

    IAction[] actions= getTemplateActions(editor);

    boolean addSurroundWith= !isInJavadoc(editor);
    if (addSurroundWith) {
      SurroundWithTryCatchAction surroundAction= createSurroundWithTryCatchAction(editor);
      ActionContributionItem surroundItem= new ActionContributionItem(surroundAction);
      surroundItem.fill(menu, -1);
    }


    boolean hasTemplateActions= actions != null && actions.length > 0;
    if (!hasTemplateActions && !addSurroundWith) {
      ActionContributionItem item= new ActionContributionItem(NONE_APPLICABLE_ACTION);
      item.fill(menu, -1);
    } else if (hasTemplateActions) {
      if (addSurroundWith) {
        Separator templateGroup= new Separator(TEMPLATE_GROUP);
        templateGroup.fill(menu, -1);
      }

      for (int i= 0; i < actions.length; i++) {
        ActionContributionItem item= new ActionContributionItem(actions[i]);
        item.fill(menu, -1);
      }
    }

    Separator configGroup= new Separator(CONFIG_GROUP);
    configGroup.fill(menu, -1);

    ActionContributionItem configAction= new ActionContributionItem(new ConfigureTemplatesAction());
    configAction.fill(menu, -1);

  }

  private static SurroundWithTryCatchAction createSurroundWithTryCatchAction(CompilationUnitEditor editor) {
    SurroundWithTryCatchAction result= new SurroundWithTryCatchAction(editor);
    result.setText(ActionMessages.SurroundWithTemplateMenuAction_SurroundWithTryCatchActionName);
    result.setActionDefinitionId(IJavaEditorActionDefinitionIds.SURROUND_WITH_TRY_CATCH);
    editor.setAction("SurroundWithTryCatch", result); //$NON-NLS-1$
    return result;
  }

  protected void initMenu() {
    fMenu.addMenuListener(new MenuAdapter() {
      public void menuShown(MenuEvent e) {
        Menu m = (Menu)e.widget;
        MenuItem[] items = m.getItems();
        for (int i=0; i < items.length; i++) {
          items[i].dispose();
        }
        fillMenu(m);
      }
    });
  }

  private void setMenu(Menu menu) {
    if (fMenu != null) {
      fMenu.dispose();
    }
    fMenu = menu;
  }

  private static IAction[] getTemplateActions(JavaEditor editor) {
    ITextSelection textSelection= getTextSelection(editor);
    if (textSelection == null || textSelection.getLength() == 0)
      return null;

    ICompilationUnit cu= JavaUI.getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
    if (cu == null)
      return null;

    QuickTemplateProcessor quickTemplateProcessor= new QuickTemplateProcessor();
    IInvocationContext context= new AssistContext(cu, textSelection.getOffset(), textSelection.getLength());

    try {
      IJavaCompletionProposal[] proposals= quickTemplateProcessor.getAssists(context, null);
      if (proposals == null || proposals.length == 0)
        return null;

      return getActionsFromProposals(proposals, context.getSelectionOffset(), editor.getViewer());
    } catch (CoreException e) {
      JavaPlugin.log(e);
    }
    return null;
  }

  private static ITextSelection getTextSelection(JavaEditor editor) {
    ISelectionProvider selectionProvider= editor.getSelectionProvider();
    if (selectionProvider == null)
      return null;

    ISelection selection= selectionProvider.getSelection();
    if (!(selection instanceof ITextSelection))
      return null;

    return (ITextSelection)selection;
  }

  private static boolean isInJavadoc(JavaEditor editor) {
    ITextSelection selection= getTextSelection(editor);
    if (selection == null)
      return false;
    
    IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
    try {
      String contentType= TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, selection.getOffset(), true);
      return contentType.equals(IJavaPartitions.JAVA_DOC);
    } catch (BadLocationException e) {
      return false;
    }
  }

  private static IAction[] getActionsFromProposals(IJavaCompletionProposal[] proposals, final int offset, final ITextViewer viewer) {
    List result= new ArrayList();

    for (int i= 0, j= 1; i < proposals.length; i++) {
      if (proposals[i] instanceof ICompletionProposalExtension2) {
        final IJavaCompletionProposal proposal= proposals[i];

        StringBuffer actionName= new StringBuffer();
        if (j<10) {
          actionName.append('&').append(j).append(' ');
        }
        actionName.append(proposals[i].getDisplayString());

        Action action= new Action(actionName.toString()) {
          /**
           * {@inheritDoc}
           */
          public void run() {
            applyProposal(proposal, viewer, (char)0, 0, offset);
          }
        };

        result.add(action);
        j++;
      }
    }
    if (result.size() == 0)
      return null;

    return (IAction[])result.toArray(new IAction[result.size()]);
  }

  private static void applyProposal(ICompletionProposal proposal, ITextViewer viewer, char trigger, int stateMask, final int offset) {
    Assert.isTrue(proposal instanceof ICompletionProposalExtension2);

    IRewriteTarget target= null;
    IEditingSupportRegistry registry= null;
    IEditingSupport helper= new IEditingSupport() {

      public boolean isOriginator(DocumentEvent event, IRegion focus) {
        return focus.getOffset() <= offset && focus.getOffset() + focus.getLength() >= offset;
      }

      public boolean ownsFocusShell() {
        return false;
      }

    };

    try {
      IDocument document= viewer.getDocument();

      if (viewer instanceof ITextViewerExtension) {
        ITextViewerExtension extension= (ITextViewerExtension) viewer;
        target= extension.getRewriteTarget();
      }

      if (target != null)
        target.beginCompoundChange();

      if (viewer instanceof IEditingSupportRegistry) {
        registry= (IEditingSupportRegistry) viewer;
        registry.register(helper);
      }

      ((ICompletionProposalExtension2)proposal).apply(viewer, trigger, stateMask, offset);

      Point selection= proposal.getSelection(document);
      if (selection != null) {
        viewer.setSelectedRange(selection.x, selection.y);
        viewer.revealRange(selection.x, selection.y);
      }
    } finally {
      if (target != null)
        target.endCompoundChange();

      if (registry != null)
        registry.unregister(helper);
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.