| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal; |
| |
| import java.util.*; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.ui.*; |
| import org.eclipse.ui.part.MultiEditor; |
| |
| /** |
| * EditorPresentation is a wrapper for PartTabworkbook. |
| */ |
| public class EditorPresentation { |
| private WorkbenchPage page; |
| private ArrayList editorTable = new ArrayList(4); |
| private EditorArea editorArea; |
| /** |
| * Creates a new EditorPresentation. |
| */ |
| public EditorPresentation(WorkbenchPage page) { |
| IPartDropListener partDropListener = new IPartDropListener() { |
| public void dragOver(PartDropEvent e) { |
| onPartDragOver(e); |
| }; |
| public void drop(PartDropEvent e){ |
| onPartDrop(e); |
| }; |
| }; |
| |
| this.page = page; |
| this.editorArea = new EditorArea(IPageLayout.ID_EDITOR_AREA, partDropListener, page); |
| } |
| /** |
| * Closes all of the editors. |
| */ |
| public void closeAllEditors() { |
| editorArea.removeAllEditors(); |
| ArrayList editorsToDispose = (ArrayList) editorTable.clone(); |
| editorTable.clear(); |
| for (int i = 0; i < editorsToDispose.size(); i++){ |
| ((EditorPane)editorsToDispose.get(i)).dispose(); |
| } |
| } |
| /** |
| * Closes an editor. |
| * |
| * @param part the editor to close |
| */ |
| public void closeEditor(IEditorReference ref) { |
| EditorPane pane = (EditorPane)((WorkbenchPartReference)ref).getPane(); |
| closeEditor(pane); |
| } |
| /** |
| * Closes an editor. |
| * |
| * @param part the editor to close |
| */ |
| public void closeEditor(IEditorPart part) { |
| EditorPane pane = (EditorPane)((PartSite)part.getEditorSite()).getPane(); |
| closeEditor(pane); |
| } |
| /** |
| * Closes an editor. |
| * |
| * @param part the editor to close |
| */ |
| private void closeEditor(EditorPane pane) { |
| if (pane != null) { |
| if (!(pane instanceof MultiEditorInnerPane)) |
| editorArea.removeEditor(pane); |
| editorTable.remove(pane); |
| pane.dispose(); |
| } |
| } |
| /** |
| * Deref a given part. Deconstruct its container as required. |
| * Do not remove drag listeners. |
| */ |
| private void derefPart(LayoutPart part) { |
| // Get vital part stats before reparenting. |
| ILayoutContainer oldContainer = part.getContainer(); |
| |
| // Reparent the part back to the main window |
| part.reparent(editorArea.getParent()); |
| // Update container. |
| if (oldContainer == null) |
| return; |
| oldContainer.remove(part); |
| LayoutPart[] children = oldContainer.getChildren(); |
| if (children == null || children.length == 0){ |
| // There are no more children in this container, so get rid of it |
| if (oldContainer instanceof LayoutPart) { |
| LayoutPart parent = (LayoutPart)oldContainer; |
| ILayoutContainer parentContainer = parent.getContainer(); |
| if (parentContainer != null) { |
| parentContainer.remove(parent); |
| parent.dispose(); |
| } |
| } |
| } |
| } |
| /** |
| * Dispose of the editor presentation. |
| */ |
| public void dispose() { |
| if (editorArea != null) { |
| editorArea.dispose(); |
| } |
| } |
| /** |
| * @see IEditorPresentation |
| */ |
| public String getActiveEditorWorkbookID() { |
| return editorArea.getActiveWorkbookID(); |
| } |
| /** |
| * Returns an array of the open editors. |
| * |
| * @return an array of open editors |
| */ |
| public IEditorReference[] getEditors() { |
| int nSize = editorTable.size(); |
| IEditorReference [] retArray = new IEditorReference[nSize]; |
| for (int i = 0; i < retArray.length; i++){ |
| retArray[i] = ((EditorPane)editorTable.get(i)).getEditorReference(); |
| } |
| return retArray; |
| } |
| /** |
| * Returns the editor area. |
| */ |
| public LayoutPart getLayoutPart() { |
| return editorArea; |
| } |
| /** |
| * Returns the active editor in this perspective. If the editors appear |
| * in a workbook this will be the visible editor. If the editors are |
| * scattered around the workbench this will be the most recent editor |
| * to hold focus. |
| * |
| * @return the active editor, or <code>null</code> if no editor is active |
| */ |
| public IEditorReference getVisibleEditor() { |
| EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook(); |
| EditorPane pane = activeWorkbook.getVisibleEditor(); |
| if (pane != null) { |
| IEditorReference result = pane.getEditorReference(); |
| IEditorPart editorPart = (IEditorPart)result.getPart(false); |
| if((editorPart != null) && (editorPart instanceof MultiEditor)) { |
| editorPart = ((MultiEditor)editorPart).getActiveEditor(); |
| EditorSite site = (EditorSite)editorPart.getSite(); |
| result = (IEditorReference)site.getPane().getPartReference(); |
| } |
| return result; |
| } |
| return null; |
| } |
| /** |
| * The active editor has failed to be restored. Find another editor, restore it |
| * and make it visible. |
| */ |
| public void fixVisibleEditor() { |
| EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook(); |
| EditorPane pane = activeWorkbook.getVisibleEditor(); |
| if(pane == null) { |
| LayoutPart editors[] = activeWorkbook.getChildren(); |
| if(editors.length > 0) |
| pane = (EditorPane)editors[0]; |
| } |
| if(pane != null) { |
| IEditorReference result = pane.getEditorReference(); |
| IEditorPart editorPart = (IEditorPart)result.getPart(true); |
| if(editorPart != null) |
| activeWorkbook.setVisibleEditor(pane); |
| } |
| } |
| |
| public void moveEditor(IEditorPart part,int position) { |
| EditorPane pane = (EditorPane)((EditorSite)part.getSite()).getPane(); |
| pane.getWorkbook().reorderTab(pane,position); |
| } |
| /** |
| * Move a part from one position to another. |
| * This implementation assumes the target is |
| * an editor workbook. |
| */ |
| private void movePart(LayoutPart part, int position, EditorWorkbook relativePart) { |
| EditorArea sashContainer = relativePart.getEditorArea(); |
| if (sashContainer == null) |
| return; |
| |
| // Remove the part from the current container. |
| derefPart(part); |
| // Add the part. |
| int relativePosition = IPageLayout.LEFT; |
| if (position == PartDragDrop.RIGHT) |
| relativePosition = IPageLayout.RIGHT; |
| else if (position == PartDragDrop.TOP) |
| relativePosition = IPageLayout.TOP; |
| else if (position == PartDragDrop.BOTTOM) |
| relativePosition = IPageLayout.BOTTOM; |
| if (part instanceof EditorWorkbook) { |
| sashContainer.add(part, relativePosition, (float) 0.5, relativePart); |
| ((EditorWorkbook)part).becomeActiveWorkbook(true); |
| } |
| else { |
| EditorWorkbook newWorkbook = new EditorWorkbook(editorArea); |
| sashContainer.add(newWorkbook, relativePosition, (float) 0.5, relativePart); |
| newWorkbook.add(part); |
| newWorkbook.becomeActiveWorkbook(true); |
| } |
| } |
| /** |
| * Notification sent during drag and drop operation. |
| * Only allow editors and editor workbooks to participate |
| * in the drag. Only allow the drop on an editor workbook |
| * within the same editor area. |
| */ |
| private void onPartDragOver(PartDropEvent e) { |
| // If source and target are in different windows reject. |
| if (e.dragSource != null && e.dropTarget != null) { |
| if (e.dragSource.getWorkbenchWindow() != e.dropTarget.getWorkbenchWindow()) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| } |
| |
| // can't detach editor into its own window |
| if (/*!detachable &&*/ e.relativePosition == PartDragDrop.OFFSCREEN){ |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| // can't drop unless over an editor workbook |
| if (!(e.dropTarget instanceof EditorWorkbook)) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| // handle drag of an editor |
| if (e.dragSource instanceof EditorPane) { |
| EditorWorkbook sourceWorkbook = ((EditorPane)e.dragSource).getWorkbook(); |
| // limitations when drop is over editor's own workbook |
| if (sourceWorkbook == e.dropTarget) { |
| // can't stack/detach/attach from same workbook when only one editor |
| if (sourceWorkbook.getItemCount() == 1) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| } |
| |
| // can't drop into another editor area |
| EditorWorkbook targetWorkbook = (EditorWorkbook)e.dropTarget; |
| if (sourceWorkbook.getEditorArea() != targetWorkbook.getEditorArea()) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| // all seems well |
| return; |
| } |
| // handle drag of an editor workbook |
| if (e.dragSource instanceof EditorWorkbook) { |
| // can't attach nor stack in same workbook |
| if (e.dragSource == e.dropTarget) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| // can't drop into another editor area |
| EditorWorkbook sourceWorkbook = (EditorWorkbook)e.dragSource; |
| EditorWorkbook targetWorkbook = (EditorWorkbook)e.dropTarget; |
| if (sourceWorkbook.getEditorArea() != targetWorkbook.getEditorArea()) { |
| e.relativePosition = PartDragDrop.INVALID; |
| return; |
| } |
| |
| // all seems well |
| return; |
| } |
| // invalid case - do not allow a drop to happen |
| e.relativePosition = PartDragDrop.INVALID; |
| } |
| /** |
| * Notification sent when drop happens. Only editors |
| * and editor workbooks were allowed to participate. |
| * Only an editor workbook in the same editor area as |
| * the drag started can accept the drop. |
| */ |
| private void onPartDrop(PartDropEvent e) { |
| switch (e.relativePosition) { |
| case PartDragDrop.OFFSCREEN: |
| // This case is not supported and should never |
| // happen. See onPartDragOver |
| //detach(e.dragSource, e.x, e.y); |
| break; |
| case PartDragDrop.CENTER: |
| if (e.dragSource instanceof EditorPane) { |
| EditorWorkbook sourceWorkbook = ((EditorPane)e.dragSource).getWorkbook(); |
| if (sourceWorkbook == e.dropTarget) { |
| sourceWorkbook.reorderTab((EditorPane)e.dragSource, e.cursorX, e.cursorY); |
| break; |
| } |
| } |
| stack(e.dragSource, (EditorWorkbook)e.dropTarget); |
| break; |
| case PartDragDrop.LEFT: |
| case PartDragDrop.RIGHT: |
| case PartDragDrop.TOP: |
| case PartDragDrop.BOTTOM: |
| if (page.isZoomed()) |
| page.zoomOut(); |
| movePart(e.dragSource, e.relativePosition, (EditorWorkbook)e.dropTarget); |
| break; |
| } |
| } |
| /** |
| * Opens an editor within the presentation. |
| * </p> |
| * @param part the editor |
| */ |
| public void openEditor(IEditorReference ref,IEditorReference[] innerEditors, boolean setVisible) { |
| EditorPane pane = new MultiEditorOuterPane(ref, page, editorArea.getActiveWorkbook()); |
| initPane(pane,ref); |
| for (int i = 0; i < innerEditors.length; i++) { |
| EditorPane innerPane = new MultiEditorInnerPane(pane,innerEditors[i], page, editorArea.getActiveWorkbook()); |
| initPane(innerPane,innerEditors[i]); |
| } |
| // Show the editor. |
| editorArea.addEditor(pane); |
| if(setVisible) |
| setVisibleEditor(ref, true); |
| } |
| /** |
| * Opens an editor within the presentation. |
| * </p> |
| * @param part the editor |
| */ |
| public void openEditor(IEditorReference ref,boolean setVisible) { |
| |
| EditorPane pane = new EditorPane(ref, page, editorArea.getActiveWorkbook()); |
| initPane(pane,ref); |
| |
| // Show the editor. |
| editorArea.addEditor(pane); |
| if(setVisible) |
| setVisibleEditor(ref, true); |
| } |
| private EditorPane initPane(EditorPane pane, IEditorReference ref) { |
| ((WorkbenchPartReference)ref).setPane(pane); |
| // Record the new editor. |
| editorTable.add(pane); |
| return pane; |
| } |
| /** |
| * @see IPersistablePart |
| */ |
| public IStatus restoreState(IMemento memento) { |
| // Restore the editor area workbooks layout/relationship |
| return editorArea.restoreState(memento); |
| } |
| /** |
| * @see IPersistablePart |
| */ |
| public IStatus saveState(IMemento memento) { |
| // Save the editor area workbooks layout/relationship |
| return editorArea.saveState(memento); |
| } |
| /** |
| * @see IEditorPresentation |
| */ |
| public void setActiveEditorWorkbookFromID(String id) { |
| editorArea.setActiveWorkbookFromID(id); |
| } |
| /** |
| * Makes sure the visible editor's tab is visible. |
| */ |
| public void showVisibleEditor() { |
| EditorWorkbook activeWorkbook = editorArea.getActiveWorkbook(); |
| if(activeWorkbook != null) |
| activeWorkbook.showVisibleEditor(); |
| } |
| /** |
| * Brings an editor to the front and gives it focus. |
| * |
| * @param part the editor to make visible |
| * @param setFocus whether to give the editor focus |
| * @return true if the active editor was changed, false if not. |
| */ |
| public boolean setVisibleEditor(IEditorReference ref, boolean setFocus) { |
| IEditorReference visibleEditor = getVisibleEditor(); |
| if (ref != visibleEditor) { |
| IEditorPart part = (IEditorPart)ref.getPart(true); |
| EditorPane pane = null; |
| if(part != null) |
| pane = (EditorPane)((PartSite)part.getEditorSite()).getPane(); |
| if (pane != null) { |
| if(pane instanceof MultiEditorInnerPane) { |
| EditorPane parentPane = ((MultiEditorInnerPane)pane).getParentPane(); |
| EditorWorkbook activeWorkbook = parentPane.getWorkbook(); |
| EditorPane activePane = activeWorkbook.getVisibleEditor(); |
| if(activePane != parentPane) |
| parentPane.getWorkbook().setVisibleEditor(parentPane); |
| else |
| return false; |
| } else { |
| pane.getWorkbook().setVisibleEditor(pane); |
| } |
| if (setFocus) |
| part.setFocus(); |
| return true; |
| } |
| } |
| return false; |
| } |
| private void stack(LayoutPart newPart, EditorWorkbook refPart) { |
| editorArea.getControl().setRedraw(false); |
| if (newPart instanceof EditorWorkbook) { |
| EditorPane visibleEditor = ((EditorWorkbook)newPart).getVisibleEditor(); |
| LayoutPart[] children = ((EditorWorkbook)newPart).getChildren(); |
| for (int i = 0; i < children.length; i++) |
| stackEditor((EditorPane)children[i], refPart); |
| if (visibleEditor != null) { |
| visibleEditor.setFocus(); |
| refPart.becomeActiveWorkbook(true); |
| refPart.setVisibleEditor(visibleEditor); |
| } |
| } |
| else { |
| stackEditor((EditorPane)newPart, refPart); |
| newPart.setFocus(); |
| refPart.becomeActiveWorkbook(true); |
| refPart.setVisibleEditor((EditorPane)newPart); |
| } |
| editorArea.getControl().setRedraw(true); |
| } |
| private void stackEditor(EditorPane newPart, EditorWorkbook refPart) { |
| // Remove the part from old container. |
| derefPart(newPart); |
| // Reparent part and add it to the workbook |
| newPart.reparent(refPart.getParent()); |
| refPart.add(newPart); |
| } |
| /** |
| * Method getWorkbooks. |
| * @return ArrayList |
| */ |
| public ArrayList getWorkbooks() { |
| return editorArea.getEditorWorkbooks(); |
| } |
| /** |
| * Open the list of editors |
| */ |
| public void openEditorList() { |
| editorArea.getActiveWorkbook().openEditorList(); |
| } |
| } |