Package org.eclipse.ui.internal

Source Code of org.eclipse.ui.internal.DetachedWindow

/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation 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
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.ui.internal;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.internal.dnd.DragUtil;
import org.eclipse.ui.internal.dnd.IDragOverListener;
import org.eclipse.ui.internal.dnd.IDropTarget;
import org.eclipse.ui.internal.presentations.PresentationFactoryUtil;
import org.eclipse.ui.internal.presentations.util.AbstractTabFolder;
import org.eclipse.ui.internal.presentations.util.AbstractTabItem;
import org.eclipse.ui.internal.presentations.util.TabbedStackPresentation;
import org.eclipse.ui.presentations.StackDropResult;


/**
* TODO: Drag from detached to fast view bar back to detached causes NPE
*
* @since 3.1
*/
public class DetachedWindow implements IDragOverListener {

    private PartStack folder;

    private WorkbenchPage page;
   
    private Rectangle bounds = new Rectangle(0,0,0,0);

    private Shell windowShell;
   
    private boolean hideViewsOnClose = true;
   
    private ShellListener shellListener = new ShellAdapter() {
        public void shellClosed(ShellEvent e) {
            handleClose();
        }
    };
   
    private Listener resizeListener = new Listener() {
        public void handleEvent(Event event) {
            Shell shell = (Shell) event.widget;
            folder.setBounds(shell.getClientArea());
        }
    };

    private IPropertyListener propertyListener = new IPropertyListener() {
        public void propertyChanged(Object source, int propId) {
            if (propId == PartStack.PROP_SELECTION) {
                activePartChanged(getPartReference(folder.getSelection()));
            }
        }
    };

    private IWorkbenchPartReference activePart;

    private IPropertyListener partPropertyListener = new IPropertyListener() {
        public void propertyChanged(Object source, int propId) {
            if (propId == IWorkbenchPartConstants.PROP_TITLE) {
                updateTitle();
            }
        }
    };
   
    /**
     * Create a new FloatingWindow.
     */
    public DetachedWindow(WorkbenchPage workbenchPage) {
        this.page = workbenchPage;
       
        folder = new ViewStack(page, false, PresentationFactoryUtil.ROLE_VIEW, null);
        folder.addListener(propertyListener);
    }

    protected void activePartChanged(IWorkbenchPartReference partReference) {
        if (activePart == partReference) {
            return;
        }
        
        if (activePart != null) {
            activePart.removePropertyListener(partPropertyListener);
        }
        activePart = partReference;
        if (partReference != null) {
            partReference.addPropertyListener(partPropertyListener);  
        }
        updateTitle();
    }

    private void updateTitle() {
        if (activePart != null) {
            // Uncomment to set the shell title to match the title of the active part
//            String text = activePart.getTitle();
//           
//            if (!text.equals(s.getText())) {
//                s.setText(text);
//            }
        }
    }

    private static IWorkbenchPartReference getPartReference(PartPane pane) {
       
        if (pane == null) {
            return null;
        }
       
        return pane.getPartReference();
    }

    public Shell getShell() {
        return windowShell;
    }
   
    public void create() {
        windowShell = ((WorkbenchWindow)page.getWorkbenchWindow()).getDetachedWindowPool().allocateShell(shellListener);
        windowShell.setData(this);
        windowShell.setText(""); //$NON-NLS-1$
        DragUtil.addDragTarget(windowShell, this);
        hideViewsOnClose = true;
        if (bounds.isEmpty()) {
            Point center = Geometry.centerPoint(page.getWorkbenchWindow().getShell().getBounds());
            Point size = new Point(300, 200);
            Point upperLeft = Geometry.subtract(center, Geometry.divide(size, 2));
           
            bounds = Geometry.createRectangle(upperLeft, size);
        }
        getShell().setBounds(bounds);

        configureShell(windowShell);
       
        createContents(windowShell);
        windowShell.layout(true);
        folder.setBounds(windowShell.getClientArea());
    }
   
   
    /**
     * Adds a visual part to this window.
     * Supports reparenting.
     */
    public void add(ViewPane part) {

        Shell shell = getShell();
        if (shell != null) {
      part.reparent(shell);
    }
        folder.add(part);
       
        // Ensure that the shell's minimum size is capable of showing the initial first tab
        // We can only do this for 'Tabbed' stacked presentations...
        if (folder.getPresentation() instanceof TabbedStackPresentation) {
          TabbedStackPresentation stack = (TabbedStackPresentation) folder.getPresentation();
         
          AbstractTabFolder tabFolder = stack.getTabFolder();
          if (tabFolder.getItemCount() == 1) {
            // Get the space that we need to show the tab
            AbstractTabItem firstItem = tabFolder.getItem(0);
            Rectangle tabRect = firstItem.getBounds();
           
            // Take the current shell 'trim' into account
            int shellHeight = windowShell.getBounds().height - windowShell.getClientArea().height;
            int shellWidth = windowShell.getBounds().width - windowShell.getClientArea().width;
           
            windowShell.setMinimumSize(tabRect.width + shellWidth, tabRect.height + shellHeight);
          }
        }
    }

    public boolean belongsToWorkbenchPage(IWorkbenchPage workbenchPage) {
        return (this.page == workbenchPage);
    }

    public boolean close() {
        hideViewsOnClose = false;
        Shell shell = getShell();
        if (shell != null) {
            shell.close();
        }
        return true;
    }
   
    /**
     * Closes this window and disposes its shell.
     */
    private boolean handleClose() {
       
        if (hideViewsOnClose) {
            List views = new ArrayList();
            collectViewPanes(views, getChildren());
            Iterator itr = views.iterator();
            while (itr.hasNext()) {
        ViewPane child = (ViewPane) itr.next();

        // Only close if closable...
        if (child.isCloseable()) {
          page.hideView(child.getViewReference());
        } else {
          page.attachView(child.getViewReference());
        }
      }
        }

        if (folder != null) {
      folder.dispose();
    }
       
        if (windowShell != null) {
            windowShell.removeListener(SWT.Resize, resizeListener);
            DragUtil.removeDragTarget(windowShell, this);
            bounds = windowShell.getBounds();

            // Unregister this detached view as a window (for key bindings).
      final IContextService contextService = (IContextService) getWorkbenchPage().getWorkbenchWindow().getWorkbench().getService(IContextService.class);
      contextService.unregisterShell(windowShell);

            windowShell.setData(null);
            windowShell = null;
        }

        return true;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.dnd.IDragOverListener#drag(org.eclipse.swt.widgets.Control, java.lang.Object, org.eclipse.swt.graphics.Point, org.eclipse.swt.graphics.Rectangle)
     */
    public IDropTarget drag(Control currentControl, Object draggedObject,
            Point position, Rectangle dragRectangle) {

        if (!(draggedObject instanceof PartPane)) {
            return null;
        }

        final PartPane sourcePart = (PartPane) draggedObject;

        if (sourcePart.getWorkbenchWindow() != page.getWorkbenchWindow()) {
            return null;
        }
   
        // Only handle the event if the source part is acceptable to the particular PartStack
        IDropTarget target = null;
        if (folder.allowsDrop(sourcePart)) {
          target = folder.getDropTarget(draggedObject, position);
         
          if (target == null) {
            Rectangle displayBounds = DragUtil.getDisplayBounds(folder.getControl());
            if (displayBounds.contains(position)) {
                target = folder.createDropTarget(sourcePart, new StackDropResult(displayBounds, null));
            } else {
                return null;
            }
          }
        }
       
        return target;
    }
   
    /**
     * Answer a list of the view panes.
     */
    private void collectViewPanes(List result, LayoutPart[] parts) {
        for (int i = 0, length = parts.length; i < length; i++) {
            LayoutPart part = parts[i];
            if (part instanceof ViewPane) {
                result.add(part);
            }
        }
    }

    /**
     * This method will be called to initialize the given Shell's layout
     */
    protected void configureShell(Shell shell) {
        updateTitle();
        shell.addListener(SWT.Resize, resizeListener);

        // Register this detached view as a window (for key bindings).
    final IContextService contextService = (IContextService) getWorkbenchPage()
        .getWorkbenchWindow().getWorkbench().getService(IContextService.class);
        contextService.registerShell(shell,
                IContextService.TYPE_WINDOW);

        page.getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(shell,
        IWorkbenchHelpContextIds.DETACHED_WINDOW);
    }

    /**
     * Override this method to create the widget tree that is used as the window's contents.
     */
    protected Control createContents(Composite parent) {
        // Create the tab folder.
        folder.createControl(parent);

        // Reparent each view in the tab folder.
        Vector detachedChildren = new Vector();
        collectViewPanes(detachedChildren, getChildren());
        Enumeration itr = detachedChildren.elements();
        while (itr.hasMoreElements()) {
            LayoutPart part = (LayoutPart) itr.nextElement();
            part.reparent(parent);
        }

        // Return tab folder control.
        return folder.getControl();
    }

    public LayoutPart[] getChildren() {
        return folder.getChildren();
    }

    public WorkbenchPage getWorkbenchPage() {
        return this.page;
    }

    /**
     * @see IPersistablePart
     */
    public void restoreState(IMemento memento) {
        // Read the bounds.
        Integer bigInt;
        bigInt = memento.getInteger(IWorkbenchConstants.TAG_X);
        int x = bigInt.intValue();
        bigInt = memento.getInteger(IWorkbenchConstants.TAG_Y);
        int y = bigInt.intValue();
        bigInt = memento.getInteger(IWorkbenchConstants.TAG_WIDTH);
        int width = bigInt.intValue();
        bigInt = memento.getInteger(IWorkbenchConstants.TAG_HEIGHT);
        int height = bigInt.intValue();
        bigInt = memento.getInteger(IWorkbenchConstants.TAG_FLOAT);

        // Set the bounds.
        bounds = new Rectangle(x, y, width, height);
        if (getShell() != null) {
            getShell().setBounds(bounds);
        }
       
        // Create the folder.
        IMemento childMem = memento.getChild(IWorkbenchConstants.TAG_FOLDER);
        if (childMem != null) {
      folder.restoreState(childMem);
    }
    }

    /**
     * @see IPersistablePart
     */
    public void saveState(IMemento memento) {
        if (getShell() != null) {
            bounds = getShell().getBounds();
        }

        // Save the bounds.
        memento.putInteger(IWorkbenchConstants.TAG_X, bounds.x);
        memento.putInteger(IWorkbenchConstants.TAG_Y, bounds.y);
        memento.putInteger(IWorkbenchConstants.TAG_WIDTH, bounds.width);
        memento.putInteger(IWorkbenchConstants.TAG_HEIGHT, bounds.height);

        // Save the views. 
        IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_FOLDER);
        folder.saveState(childMem);
    }
   
    /* (non-Javadoc)
     * @see org.eclipse.ui.internal.IWorkbenchDragDropPart#getControl()
     */
    public Control getControl() {
        return folder.getControl();
    }
   
    /**
     * Opens the detached window.
     */
  public int open() {
    
    if (getShell() == null) {
      create();
    }

    Rectangle bounds = getShell().getBounds();
        getShell().setVisible(true);
    
    if (!bounds.equals(getShell().getBounds())) {
      getShell().setBounds(bounds);
    }
    
    return Window.OK;
  }
   
}
TOP

Related Classes of org.eclipse.ui.internal.DetachedWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.