/** * Copyright (c) 2009, 2014 Mark Feber, MulgaSoft * * 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.mulgasoft.emacsplus.e4.commands; import java.util.ArrayList; import java.util.List; import org.eclipse.core.commands.Command; import org.eclipse.e4.core.contexts.Active; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; import org.eclipse.jface.bindings.TriggerSequence; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.keys.IBindingService; import com.mulgasoft.emacsplus.Beeper; import com.mulgasoft.emacsplus.EmacsPlusUtils; import com.mulgasoft.emacsplus.commands.EmacsPlusCmdHandler; /** * Implements: open-declaration-other-window * * @author mfeber - Initial API and implementation */ public class WindowDeclOtherCmd extends SwitchToBufferOtherCmd { private static final String OD = "Open Declaration"; //$NON-NLS-1$ @Execute public Object execute(@Active MPart apart, @Active IEditorPart editor, @Active MWindow mwin, @Active EmacsPlusCmdHandler handler) { try { this.apart = apart; this.handler = handler; Command ex = getOpenCmd(editor); if (ex != null) { MUIElement area = getEditArea(application.getChildren().get(0)); MUIElement osel = getSelected(area); EmacsPlusUtils.executeCommand(ex.getId(), null); MUIElement sel = getSelected(area); // see if it was able to open a declaration if (sel instanceof MPart && sel != apart && sel != osel) { // another way of determining if we're main or frame if (!mwin.getTags().contains(TOP_TAG) && !handler.isUniversalPresent()) { // If they're in different frames, move copy to source frame first modelService.move(sel, getParentStack(apart).getStack(), 0); }; switchTo((MPart)sel); } } } catch (Exception e) { // Shouldn't happen Beeper.beep(); } return null; } /** * A bit of hackery that tries to get the correct open-declaration command for the buffer * @param editor * @return the best match Command definition */ private Command getOpenCmd(IEditorPart editor) { Command result = null; try { IBindingService bs = (IBindingService) PlatformUI.getWorkbench().getService(IBindingService.class); ICommandService ics = (ICommandService) editor.getSite().getService(ICommandService.class); List<Command> cans = new ArrayList<Command>(); List<Command> nocans = new ArrayList<Command>(); Command[] commands = ics.getDefinedCommands(); for (Command c : commands) { if (OD.equals(c.getName()) && c.isEnabled()) { TriggerSequence[] b = bs.getActiveBindingsFor(c.getId()); if (b.length > 0) { cans.add(c); } else { nocans.add(c); } } } // TODO: when > 1 try to refine the result heuristically? // if Eclipse returned more than one, then chose a bound command over non-bound if (cans.isEmpty()) { if (!nocans.isEmpty()) { // just grab first one result = nocans.get(0); } } else { // grab the first bound one result = cans.get(0); } } catch (Exception e) { } return result; } }