/******************************************************************************* * Copyright (c) 2014, 2015 Cisco Systems, Inc. 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 * *******************************************************************************/ package com.cisco.yangide.ext.refactoring; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionGroup; import com.cisco.yangide.core.YangModelException; import com.cisco.yangide.core.dom.Module; import com.cisco.yangide.editor.editors.IActionGroup; import com.cisco.yangide.editor.editors.YangEditor; import com.cisco.yangide.ext.refactoring.actions.ChangeRevisionAction; import com.cisco.yangide.ext.refactoring.actions.ExtractGroupingAction; import com.cisco.yangide.ext.refactoring.actions.InlineGroupingAction; import com.cisco.yangide.ext.refactoring.actions.RenameAction; import com.cisco.yangide.ext.refactoring.actions.SelectionDispatchAction; import com.cisco.yangide.ext.refactoring.nls.Messages; /** * @author Konstantin Zaitsev * @date Jul 29, 2014 */ public class RefactorActionGroup extends ActionGroup implements IActionGroup { private static final String RENAME_ACTION_ID = "com.cisco.yangide.ui.actions.Rename"; //$NON-NLS-1$ private static final String RENAME_DEF_ID = "com.cisco.yangide.ext.rename.element"; //$NON-NLS-1$ private static final String INLINE_GROUP_ACTION_ID = "com.cisco.yangide.ui.actions.Inline"; //$NON-NLS-1$ private static final String INLINE_GROUP_DEF_ID = "com.cisco.yangide.ext.group.inline.element"; //$NON-NLS-1$ private static final String REVISION_ACTION_ID = "com.cisco.yangide.ui.actions.Revision"; //$NON-NLS-1$ private static final String REVISION_DEF_ID = "com.cisco.yangide.ext.change.revision"; //$NON-NLS-1$ private static final String EXTRACT_ACTION_ID = "com.cisco.yangide.ui.actions.ExtractGrouping"; //$NON-NLS-1$ private static final String EXTRACT_DEF_ID = "com.cisco.yangide.ext.extract.grouping"; //$NON-NLS-1$ private static final String REFACTORING_MENU_ID = "com.cisco.yangide.ext.refactoring.menu"; //$NON-NLS-1$ /** Context menu group id. */ private static final String REORG_GROUP_ID = "reorgGroup"; //$NON-NLS-1$ private YangEditor editor; private String groupName; private ISelectionProvider selectionProvider; private SelectionDispatchAction renameAction; private SelectionDispatchAction inlineAction; private SelectionDispatchAction revisionAction; private SelectionDispatchAction extractAction; private final List<SelectionDispatchAction> actions = new ArrayList<SelectionDispatchAction>(); private static class NoActionAvailable extends Action { public NoActionAvailable() { setEnabled(true); setText(Messages.RefactorActionGroup_noRefactorAvailable); } } private Action noActionAvailable = new NoActionAvailable(); private StyledText control; @Override public void init(YangEditor editor, String groupName) { this.selectionProvider = editor.getSelectionProvider(); this.editor = editor; this.groupName = groupName; this.control = (StyledText) editor.getAdapter(Control.class); ISelection selection = selectionProvider.getSelection(); renameAction = new RenameAction(editor); initAction(renameAction, selection, RENAME_DEF_ID); editor.setAction("RenameElement", renameAction); //$NON-NLS-1$ inlineAction = new InlineGroupingAction(editor); initAction(inlineAction, selection, INLINE_GROUP_DEF_ID); editor.setAction("InlineElement", inlineAction); //$NON-NLS-1$ revisionAction = new ChangeRevisionAction(editor); initAction(revisionAction, selection, REVISION_DEF_ID); editor.setAction("ChangeRevision", revisionAction); //$NON-NLS-1$ extractAction = new ExtractGroupingAction(editor); initAction(extractAction, selection, EXTRACT_DEF_ID); editor.setAction("ExtractGrouping", extractAction); //$NON-NLS-1$ } @Override public void fillActionBars(IActionBars actionBars) { actionBars.setGlobalActionHandler(RENAME_ACTION_ID, renameAction); actionBars.setGlobalActionHandler(INLINE_GROUP_ACTION_ID, inlineAction); actionBars.setGlobalActionHandler(REVISION_ACTION_ID, revisionAction); actionBars.setGlobalActionHandler(EXTRACT_ACTION_ID, extractAction); } /** * Retargets the File actions with the corresponding refactoring actions. * * @param actionBars the action bar to register the move and rename action with */ public void retargetFileMenuActions(IActionBars actionBars) { actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(), renameAction); } @Override public void fillContextMenu(IMenuManager menu) { addRefactorSubmenu(menu); } @Override public void dispose() { disposeAction(renameAction); super.dispose(); } private void initAction(SelectionDispatchAction action, ISelection selection, String actionDefinitionId) { initUpdatingAction(action, selection, actionDefinitionId); } private void initUpdatingAction(SelectionDispatchAction action, ISelection selection, String actionDefinitionId) { action.setActionDefinitionId(actionDefinitionId); action.update(selection); if (selectionProvider != null) { selectionProvider.addSelectionChangedListener(action); } if (control != null) { control.addCaretListener(action); } actions.add(action); } private void disposeAction(SelectionDispatchAction action) { if (action != null) { selectionProvider.removeSelectionChangedListener(action); if (!control.isDisposed()) { control.removeCaretListener(action); } } } private void addRefactorSubmenu(IMenuManager menu) { MenuManager refactorSubmenu = new MenuManager(Messages.RefactorActionGroup_Refactor, REFACTORING_MENU_ID); if (editor != null) { if (editor.isEditable() && getModule() != null) { refactorSubmenu.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { refactorMenuShown(manager); } }); } menu.appendToGroup(groupName, refactorSubmenu); refactorSubmenu.add(noActionAvailable); } else { ISelection selection = selectionProvider.getSelection(); for (Iterator<SelectionDispatchAction> iter = actions.iterator(); iter.hasNext();) { iter.next().update(selection); } if (fillRefactorMenu(refactorSubmenu) > 0) { menu.appendToGroup(groupName, refactorSubmenu); } } } private int fillRefactorMenu(IMenuManager refactorSubmenu) { int added = 0; refactorSubmenu.add(new Separator(REORG_GROUP_ID)); added += addAction(refactorSubmenu, renameAction); added += addAction(refactorSubmenu, inlineAction); added += addAction(refactorSubmenu, revisionAction); added += addAction(refactorSubmenu, extractAction); return added; } private int addAction(IMenuManager menu, IAction action) { if (action != null && action.isEnabled()) { menu.add(action); return 1; } return 0; } private void refactorMenuShown(IMenuManager refactorSubmenu) { Menu menu = ((MenuManager) refactorSubmenu).getMenu(); menu.addMenuListener(new MenuAdapter() { @Override public void menuHidden(MenuEvent e) { refactorMenuHidden(); } }); ITextSelection textSelection = (ITextSelection) editor.getSelectionProvider().getSelection(); for (Iterator<SelectionDispatchAction> iter = actions.iterator(); iter.hasNext();) { SelectionDispatchAction action = iter.next(); action.update(textSelection); } refactorSubmenu.removeAll(); if (fillRefactorMenu(refactorSubmenu) == 0) { refactorSubmenu.add(noActionAvailable); } } private void refactorMenuHidden() { ITextSelection textSelection = (ITextSelection) editor.getSelectionProvider().getSelection(); for (Iterator<SelectionDispatchAction> iter = actions.iterator(); iter.hasNext();) { SelectionDispatchAction action = iter.next(); action.update(textSelection); } } private Module getModule() { try { return editor.getModule(); } catch (YangModelException e) { // ignore exception return null; } } }