/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.part.editor.multipart;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.ide.api.constraints.Constraints;
import org.eclipse.che.ide.api.editor.EditorPartPresenter;
import org.eclipse.che.ide.api.event.ActivePartChangedEvent;
import org.eclipse.che.ide.api.event.ActivePartChangedHandler;
import org.eclipse.che.ide.api.parts.EditorMultiPartStack;
import org.eclipse.che.ide.api.parts.EditorMultiPartStackState;
import org.eclipse.che.ide.api.parts.EditorPartStack;
import org.eclipse.che.ide.api.parts.EditorTab;
import org.eclipse.che.ide.api.parts.PartPresenter;
import javax.validation.constraints.NotNull;
import java.util.LinkedList;
import java.util.List;
/**
* Presenter to control the displaying of multi editors.
*
* @author Roman Nikitenko
*/
@Singleton
public class EditorMultiPartStackPresenter implements EditorMultiPartStack,
ActivePartChangedHandler {
private final Provider<EditorPartStack> editorPartStackFactory;
private final EditorMultiPartStackView view;
private final LinkedList<EditorPartStack> partStackPresenters;
private PartPresenter activeEditor;
private EditorPartStack activeEditorPartStack;
private State state = State.NORMAL;
@Inject
public EditorMultiPartStackPresenter(EventBus eventBus,
EditorMultiPartStackView view,
Provider<EditorPartStack> editorPartStackFactory) {
this.view = view;
this.editorPartStackFactory = editorPartStackFactory;
this.partStackPresenters = new LinkedList<>();
eventBus.addHandler(ActivePartChangedEvent.TYPE, this);
}
@Override
public void setDelegate(ActionDelegate delegate) {
}
@Override
public void go(AcceptsOneWidget container) {
container.setWidget(view);
}
@Override
public boolean containsPart(PartPresenter part) {
for (EditorPartStack partStackPresenter : partStackPresenters) {
if (partStackPresenter.containsPart(part)) {
return true;
}
}
return false;
}
/** {@inheritDoc} */
@Override
public void addPart(@NotNull PartPresenter part) {
if (activeEditorPartStack != null) {
//open the part in the active editorPartStack
activeEditorPartStack.addPart(part);
return;
}
//open the part in the new editorPartStack
addEditorPartStack(part, null, null, -1);
}
/** {@inheritDoc} */
@Override
public void addPart(@NotNull PartPresenter part, Constraints constraint) {
if (constraint == null) {
addPart(part);
return;
}
EditorPartStack relativePartStack = getPartStackByTabId(constraint.relativeId);
if (relativePartStack != null) {
//view of relativePartStack will be split corresponding to constraint on two areas and part will be added into created area
addEditorPartStack(part, relativePartStack, constraint, -1);
}
}
private EditorPartStack addEditorPartStack(final PartPresenter part, final EditorPartStack relativePartStack,
final Constraints constraints, double size) {
final EditorPartStack editorPartStack = editorPartStackFactory.get();
partStackPresenters.add(editorPartStack);
view.addPartStack(editorPartStack, relativePartStack, constraints, size);
if (part != null) {
editorPartStack.addPart(part);
}
return editorPartStack;
}
@Override
public void setFocus(boolean focused) {
if (activeEditorPartStack != null) {
activeEditorPartStack.setFocus(focused);
}
}
/** {@inheritDoc} */
@Override
public PartPresenter getActivePart() {
return activeEditor;
}
/** {@inheritDoc} */
@Override
public void setActivePart(@NotNull PartPresenter part) {
activeEditor = part;
EditorPartStack editorPartStack = getPartStackByPart(part);
if (editorPartStack != null) {
activeEditorPartStack = editorPartStack;
editorPartStack.setActivePart(part);
}
}
@Override
public void maximize() {
state = State.MAXIMIZED;
}
@Override
public void collapse() {
state = State.COLLAPSED;
}
@Override
public void minimize() {
state = State.MINIMIZED;
}
@Override
public void restore() {
state = State.NORMAL;
}
@Override
public State getPartStackState() {
return state;
}
@Override
public void showPartMenu(int mouseX, int mouseY) {
}
/** {@inheritDoc} */
@Override
public void removePart(PartPresenter part) {
EditorPartStack editorPartStack = getPartStackByPart(part);
if (editorPartStack == null) {
return;
}
editorPartStack.removePart(part);
if (editorPartStack.getActivePart() == null) {
removePartStack(editorPartStack);
}
}
private void removePartStack(EditorPartStack editorPartStack) {
if (activeEditorPartStack == editorPartStack) {
activeEditorPartStack = null;
}
view.removePartStack(editorPartStack);
partStackPresenters.remove(editorPartStack);
if (!partStackPresenters.isEmpty()) {
EditorPartStack lastStackPresenter = partStackPresenters.getLast();
lastStackPresenter.openPreviousActivePart();
}
}
@Override
public void openPreviousActivePart() {
if (activeEditor != null) {
getPartStackByPart(activeEditor).openPreviousActivePart();
}
}
@Override
public void updateStack() {
for (EditorPartStack editorPartStack : partStackPresenters) {
editorPartStack.updateStack();
}
}
@Override
public EditorPartStack getActivePartStack() {
return activeEditorPartStack;
}
@Override
public List<EditorPartPresenter> getParts() {
throw new UnsupportedOperationException();
}
@Nullable
public EditorPartStack getPartStackByPart(PartPresenter part) {
if (part == null) {
return null;
}
for (EditorPartStack editorPartStack : partStackPresenters) {
if (editorPartStack.containsPart(part)) {
return editorPartStack;
}
}
return null;
}
@Nullable
private EditorPartStack getPartStackByTabId(@NotNull String tabId) {
for (EditorPartStack editorPartStack : partStackPresenters) {
PartPresenter editorPart = editorPartStack.getPartByTabId(tabId);
if (editorPart != null) {
return editorPartStack;
}
}
return null;
}
@Override
public EditorPartPresenter getPartByTabId(@NotNull String tabId) {
for (EditorPartStack editorPartStack : partStackPresenters) {
EditorPartPresenter editorPart = editorPartStack.getPartByTabId(tabId);
if (editorPart != null) {
return editorPart;
}
}
return null;
}
@Override
public EditorTab getTabByPart(EditorPartPresenter editorPart) {
for (EditorPartStack editorPartStack : partStackPresenters) {
EditorTab editorTab = editorPartStack.getTabByPart(editorPart);
if (editorTab != null) {
return editorTab;
}
}
return null;
}
@Override
public EditorPartPresenter getNextFor(EditorPartPresenter editorPart) {
for (EditorPartStack editorPartStack : partStackPresenters) {
if (editorPartStack.containsPart(editorPart)) {
return editorPartStack.getNextFor(editorPart);
}
}
return null;
}
@Override
public EditorPartPresenter getPreviousFor(EditorPartPresenter editorPart) {
for (EditorPartStack editorPartStack : partStackPresenters) {
if (editorPartStack.containsPart(editorPart)) {
return editorPartStack.getPreviousFor(editorPart);
}
}
return null;
}
@Override
public EditorPartStack createRootPartStack() {
EditorPartStack editorPartStack = addEditorPartStack(null, null, null, -1);
activeEditorPartStack = editorPartStack;
return editorPartStack;
}
@Override
public EditorPartStack split(EditorPartStack relativePartStack, Constraints constraints, double size) {
EditorPartStack editorPartStack = addEditorPartStack(null, relativePartStack, constraints, size);
activeEditorPartStack = editorPartStack;
return editorPartStack;
}
@Override
public EditorMultiPartStackState getState() {
return view.getState();
}
@Override
public void onActivePartChanged(ActivePartChangedEvent event) {
PartPresenter activePart = event.getActivePart();
if (activePart instanceof EditorPartPresenter) {
activeEditor = activePart;
activeEditorPartStack = getPartStackByPart(activePart);
}
}
}