/** * 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.Collection; import java.util.List; import org.eclipse.e4.ui.model.application.ui.MElementContainer; 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.MTrimmedWindow; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.ui.IEditorPart; import com.mulgasoft.emacsplus.Beeper; /** * join-other-frames: Join all frames to the main frame * join-frame: Join frame to the main frame * * @author mfeber - Initial API and implementation */ public class FrameJoinCmd extends WindowJoinCmd { boolean joined = true; @Override void joinAll(MPart apart) { joined = true; List<MTrimmedWindow> frames = getDetachedFrames(); MElementContainer<MUIElement> last = getTopElement((MElementContainer<MUIElement>) apart.getParent()); for (MTrimmedWindow mt : frames) { if (!mt.equals(last)) { joinOne(mt); } } // only join apart if its top element is a frame if ((Object)last instanceof MTrimmedWindow) { super.joinOne(apart); } } void joinOne(MTrimmedWindow mt) { // As long as it has any editor MParts, we can join it List<MPart> parts = getParts(mt, EModelService.IN_ANY_PERSPECTIVE); if (!parts.isEmpty()) { super.joinOne(parts.get(0)); } } @Override MPart joinOne(MPart apart) { joined = true; if ((Object)getTopElement(apart.getParent()) instanceof MTrimmedWindow) { return super.joinOne(apart); } else { joined = false; Beeper.beep(); } return apart; } private List<MPart> getParts(MUIElement element, int location) { return modelService.findElements(element, null, MPart.class, EDITOR_TAG, location); } protected MElementContainer<MUIElement> join2Stacks(MElementContainer<MUIElement> pstack, MElementContainer<MUIElement> dropStack, MPart apart) { // pstack may have been merged away by our getAdjacentElement, so fetch current one if necessary MElementContainer<MUIElement> stack = (pstack.getChildren().isEmpty() ? getParentStack(apart).getStack() : pstack); return super.join2Stacks(stack, dropStack, apart); } /** * @see com.mulgasoft.emacsplus.e4.commands.E4WindowCmd#getAdjacentElement(org.eclipse.e4.ui.model.application.ui.MElementContainer, boolean, org.eclipse.e4.ui.model.application.ui.basic.MPart) */ protected MElementContainer<MUIElement> getAdjacentElement(MElementContainer<MUIElement> dragStack, MPart part, boolean stackp) { MElementContainer<MUIElement> result = null; if (dragStack != null) { MElementContainer<MUIElement> psash = dragStack.getParent(); MElementContainer<MUIElement> top = getTopElement(psash); if ((Object)top instanceof MTrimmedWindow) { // if we contain splits, remove them first if (top != psash) { super.joinAll(part); } Collection<MPart> parts = getParts(application.getChildren().get(0), EModelService.IN_SHARED_AREA); for (MPart p : parts) { List<MElementContainer<MUIElement>> all = getOrderedStacks(p); // if it has a PartStack, it sh/c/ould be an editor stack if (!all.isEmpty()) { result = all.get(0); break; }; }; } } return result; } protected boolean preJoin(IEditorPart editor) {return false;} protected void postJoin(IEditorPart editor) { if (joined) { closeOthers(editor); } } protected void checkSizeData(MElementContainer<MUIElement> pstack, MElementContainer<MUIElement> dropStack) { // no-op don't change anything on frame merge } }