Source Code Cross Referenced for PerspectiveHelper.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » internal » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.ui.internal;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Collections;
0014:        import java.util.Enumeration;
0015:        import java.util.HashMap;
0016:        import java.util.List;
0017:        import java.util.Map;
0018:        import java.util.Vector;
0019:
0020:        import org.eclipse.core.runtime.IStatus;
0021:        import org.eclipse.jface.preference.IPreferenceStore;
0022:        import org.eclipse.swt.SWT;
0023:        import org.eclipse.swt.graphics.Cursor;
0024:        import org.eclipse.swt.graphics.Point;
0025:        import org.eclipse.swt.graphics.Rectangle;
0026:        import org.eclipse.swt.widgets.Composite;
0027:        import org.eclipse.swt.widgets.Control;
0028:        import org.eclipse.swt.widgets.Shell;
0029:        import org.eclipse.ui.IMemento;
0030:        import org.eclipse.ui.IViewReference;
0031:        import org.eclipse.ui.IWorkbenchPartReference;
0032:        import org.eclipse.ui.IWorkbenchPreferenceConstants;
0033:        import org.eclipse.ui.PlatformUI;
0034:        import org.eclipse.ui.internal.dnd.AbstractDropTarget;
0035:        import org.eclipse.ui.internal.dnd.DragUtil;
0036:        import org.eclipse.ui.internal.dnd.IDragOverListener;
0037:        import org.eclipse.ui.internal.dnd.IDropTarget;
0038:        import org.eclipse.ui.internal.misc.StringMatcher;
0039:        import org.eclipse.ui.presentations.IStackPresentationSite;
0040:
0041:        /**
0042:         * A perspective presentation is a collection of parts with a layout. Each part
0043:         * is parented to a main window, so you can create more than one presentation
0044:         * on a set of parts and change the layout just by activating / deactivating a
0045:         * presentation.
0046:         * 
0047:         * In addition, the user can change the position of any part by mouse
0048:         * manipulation (drag & drop). If a part is removed, we leave a placeholder
0049:         * behind to indicate where it goes should the part be added back.
0050:         */
0051:        public class PerspectiveHelper {
0052:            private WorkbenchPage page;
0053:
0054:            private Perspective perspective;
0055:
0056:            private Composite parentWidget;
0057:
0058:            private ViewSashContainer mainLayout;
0059:
0060:            private PartStack maximizedStack;
0061:
0062:            /**
0063:             * If there is a ViewStack maximized on shutdown the id is
0064:             * cached and restored into this field on 'restoreState'.
0065:             * This is then used to bash the ViewStack's presentation state
0066:             * into the correct value on activation (the startup life-cycle
0067:             * is such that we have to use this 'latch' because the window
0068:             * state isn't valid until the activate happens.
0069:             */
0070:            private String maximizedStackId;
0071:
0072:            private ArrayList detachedWindowList = new ArrayList(1);
0073:
0074:            private ArrayList detachedPlaceHolderList = new ArrayList(1);
0075:
0076:            /**
0077:             * Maps a stack's id to its current bounds
0078:             * this is used to capture the current bounds of all
0079:             * stacks -before- starting a maximize (since the
0080:             * iterative 'minimize' calls cause the intial stack's
0081:             * bounds to change.
0082:             */
0083:            private Map boundsMap = new HashMap();
0084:
0085:            private boolean detachable = false;
0086:
0087:            private boolean active = false;
0088:
0089:            // key is the LayoutPart object, value is the PartDragDrop object
0090:            //private IPartDropListener partDropListener;
0091:
0092:            private static final int MIN_DETACH_WIDTH = 150;
0093:
0094:            private static final int MIN_DETACH_HEIGHT = 250;
0095:
0096:            protected ActualDropTarget dropTarget;
0097:
0098:            private IDragOverListener dragTarget = new IDragOverListener() {
0099:
0100:                public IDropTarget drag(Control currentControl,
0101:                        Object draggedObject, Point position,
0102:                        final Rectangle dragRectangle) {
0103:
0104:                    if (!(draggedObject instanceof  ViewPane || draggedObject instanceof  ViewStack)) {
0105:                        return null;
0106:                    }
0107:                    final LayoutPart part = (LayoutPart) draggedObject;
0108:
0109:                    if (part.getWorkbenchWindow() != page.getWorkbenchWindow()) {
0110:                        return null;
0111:                    }
0112:
0113:                    if (dropTarget == null) {
0114:                        dropTarget = new ActualDropTarget(part, dragRectangle);
0115:                    } else {
0116:                        dropTarget.setTarget(part, dragRectangle);
0117:                    }
0118:
0119:                    return dropTarget;
0120:                }
0121:
0122:            };
0123:
0124:            private final class ActualDropTarget extends AbstractDropTarget {
0125:                private LayoutPart part;
0126:
0127:                private Rectangle dragRectangle;
0128:
0129:                private ActualDropTarget(LayoutPart part,
0130:                        Rectangle dragRectangle) {
0131:                    super ();
0132:                    setTarget(part, dragRectangle);
0133:                }
0134:
0135:                /**
0136:                 * @param part
0137:                 * @param dragRectangle
0138:                 * @since 3.1
0139:                 */
0140:                private void setTarget(LayoutPart part, Rectangle dragRectangle) {
0141:                    this .part = part;
0142:                    this .dragRectangle = dragRectangle;
0143:                }
0144:
0145:                public void drop() {
0146:
0147:                    Shell shell = part.getShell();
0148:                    if (shell.getData() instanceof  DetachedWindow) {
0149:                        // only one tab folder in a detach window, so do window
0150:                        // move
0151:                        if (part instanceof  ViewStack) {
0152:                            shell.setLocation(dragRectangle.x, dragRectangle.y);
0153:                            return;
0154:                        }
0155:                        // if only one view in tab folder then do a window move
0156:                        ILayoutContainer container = part.getContainer();
0157:                        if (container instanceof  ViewStack) {
0158:                            if (((ViewStack) container).getItemCount() == 1) {
0159:                                shell.setLocation(dragRectangle.x,
0160:                                        dragRectangle.y);
0161:                                return;
0162:                            }
0163:                        }
0164:                    }
0165:
0166:                    // If layout is modified always zoom out.
0167:                    if (isZoomed()) {
0168:                        zoomOut();
0169:                    }
0170:                    // do a normal part detach
0171:                    detach(part, dragRectangle.x, dragRectangle.y);
0172:                }
0173:
0174:                public Cursor getCursor() {
0175:                    return DragCursors.getCursor(DragCursors.OFFSCREEN);
0176:                }
0177:            }
0178:
0179:            private class MatchingPart implements  Comparable {
0180:                String pid;
0181:
0182:                String sid;
0183:
0184:                LayoutPart part;
0185:
0186:                boolean hasWildcard;
0187:
0188:                int len;
0189:
0190:                MatchingPart(String pid, String sid, LayoutPart part) {
0191:                    this .pid = pid;
0192:                    this .sid = sid;
0193:                    this .part = part;
0194:                    this .len = (pid == null ? 0 : pid.length())
0195:                            + (sid == null ? 0 : sid.length());
0196:                    this .hasWildcard = (pid != null && pid
0197:                            .indexOf(PartPlaceholder.WILD_CARD) != -1)
0198:                            || (sid != null && sid
0199:                                    .indexOf(PartPlaceholder.WILD_CARD) != -1);
0200:                }
0201:
0202:                public int compareTo(Object a) {
0203:                    // specific ids always outweigh ids with wildcards
0204:                    MatchingPart ma = (MatchingPart) a;
0205:                    if (this .hasWildcard && !ma.hasWildcard) {
0206:                        return -1;
0207:                    }
0208:                    if (!this .hasWildcard && ma.hasWildcard) {
0209:                        return 1;
0210:                    }
0211:                    // if both are specific or both have wildcards, simply compare based on length
0212:                    return ma.len - this .len;
0213:                }
0214:            }
0215:
0216:            /**
0217:             * Constructs a new object.
0218:             */
0219:            public PerspectiveHelper(WorkbenchPage workbenchPage,
0220:                    ViewSashContainer mainLayout, Perspective perspective) {
0221:                this .page = workbenchPage;
0222:                this .mainLayout = mainLayout;
0223:                this .perspective = perspective;
0224:
0225:                // Views can be detached if the feature is enabled (true by default,
0226:                // use the plug-in customization file to disable), and if the platform
0227:                // supports detaching.
0228:
0229:                final IPreferenceStore store = PlatformUI.getPreferenceStore();
0230:                this .detachable = store
0231:                        .getBoolean(IWorkbenchPreferenceConstants.ENABLE_DETACHED_VIEWS);
0232:
0233:                if (this .detachable) {
0234:                    // Check if some arbitrary Composite supports reparenting. If it
0235:                    // doesn't, views cannot be detached.
0236:
0237:                    Composite client = workbenchPage.getClientComposite();
0238:                    if (client == null) {
0239:                        // The workbench page is not initialized. I don't think this can happen,
0240:                        // but if it does, silently set detachable to false.
0241:                        this .detachable = false;
0242:                    } else {
0243:                        Composite testChild = new Composite(client, SWT.NONE);
0244:                        this .detachable = testChild.isReparentable();
0245:                        testChild.dispose();
0246:                    }
0247:                }
0248:            }
0249:
0250:            /**
0251:             * Show the presentation.
0252:             */
0253:            public void activate(Composite parent) {
0254:
0255:                if (active) {
0256:                    return;
0257:                }
0258:
0259:                parentWidget = parent;
0260:
0261:                // Activate main layout
0262:                // make sure all the views have been properly parented
0263:                Vector children = new Vector();
0264:                collectViewPanes(children, mainLayout.getChildren());
0265:                Enumeration itr = children.elements();
0266:                while (itr.hasMoreElements()) {
0267:                    LayoutPart part = (LayoutPart) itr.nextElement();
0268:                    part.reparent(parent);
0269:                }
0270:                mainLayout.createControl(parent);
0271:                mainLayout.setActive(true);
0272:
0273:                // Open the detached windows.
0274:                for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0275:                    DetachedWindow dwindow = (DetachedWindow) detachedWindowList
0276:                            .get(i);
0277:                    dwindow.open();
0278:                }
0279:
0280:                enableAllDrag();
0281:
0282:                // Ensure that the maximized stack's presentation state is correct
0283:                if (maximizedStackId != null) {
0284:                    LayoutPart part = findPart(maximizedStackId);
0285:                    if (part instanceof  PartStack) {
0286:                        maximizedStack = (PartStack) part;
0287:                        maximizedStackId = null;
0288:                    }
0289:                }
0290:
0291:                // NOTE: we only handle ViewStacks here; Editor Stacks are handled by the
0292:                // perspective
0293:                if (maximizedStack instanceof  ViewStack) {
0294:                    maximizedStack
0295:                            .setPresentationState(IStackPresentationSite.STATE_MAXIMIZED);
0296:                }
0297:
0298:                active = true;
0299:            }
0300:
0301:            /**
0302:             * Adds a part to the presentation. If a placeholder exists for the part
0303:             * then swap the part in. Otherwise, add the part in the bottom right
0304:             * corner of the presentation.
0305:             */
0306:            public void addPart(LayoutPart part) {
0307:
0308:                // Look for a placeholder.
0309:                PartPlaceholder placeholder = null;
0310:                LayoutPart testPart = null;
0311:                String primaryId = part.getID();
0312:                String secondaryId = null;
0313:
0314:                IViewReference ref = null;
0315:                if (part instanceof  ViewPane) {
0316:                    ViewPane pane = (ViewPane) part;
0317:                    ref = (IViewReference) pane.getPartReference();
0318:                    secondaryId = ref.getSecondaryId();
0319:                }
0320:                if (secondaryId != null) {
0321:                    testPart = findPart(primaryId, secondaryId);
0322:                } else {
0323:                    testPart = findPart(primaryId);
0324:                }
0325:
0326:                // validate the testPart
0327:                if (testPart != null && testPart instanceof  PartPlaceholder) {
0328:                    placeholder = (PartPlaceholder) testPart;
0329:                }
0330:
0331:                // If there is no placeholder do a simple add. Otherwise, replace the
0332:                // placeholder if its not a pattern matching placholder
0333:                if (placeholder == null) {
0334:                    part.reparent(mainLayout.getParent());
0335:                    LayoutPart relative = mainLayout.findBottomRight();
0336:                    if (relative != null
0337:                            && relative instanceof  ILayoutContainer) {
0338:                        ILayoutContainer stack = (ILayoutContainer) relative;
0339:                        if (stack.allowsAdd(part)) {
0340:                            mainLayout.stack(part, stack);
0341:                        } else {
0342:                            mainLayout.add(part);
0343:                        }
0344:                    } else {
0345:                        mainLayout.add(part);
0346:                    }
0347:                } else {
0348:                    ILayoutContainer container = placeholder.getContainer();
0349:                    if (container != null) {
0350:                        if (container instanceof  DetachedPlaceHolder) {
0351:                            //Create a detached window add the part on it.
0352:                            DetachedPlaceHolder holder = (DetachedPlaceHolder) container;
0353:                            detachedPlaceHolderList.remove(holder);
0354:                            container.remove(testPart);
0355:                            DetachedWindow window = new DetachedWindow(page);
0356:                            detachedWindowList.add(window);
0357:                            window.create();
0358:                            part.createControl(window.getShell());
0359:                            // Open window.
0360:                            window.getShell().setBounds(holder.getBounds());
0361:                            window.open();
0362:                            // add part to detached window.
0363:                            ViewPane pane = (ViewPane) part;
0364:                            window.add(pane);
0365:                            LayoutPart otherChildren[] = holder.getChildren();
0366:                            for (int i = 0; i < otherChildren.length; i++) {
0367:                                part.getContainer().add(otherChildren[i]);
0368:                            }
0369:                        } else {
0370:                            // show parent if necessary
0371:                            if (container instanceof  ContainerPlaceholder) {
0372:                                ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container;
0373:                                ILayoutContainer parentContainer = containerPlaceholder
0374:                                        .getContainer();
0375:                                container = (ILayoutContainer) containerPlaceholder
0376:                                        .getRealContainer();
0377:                                if (container instanceof  LayoutPart) {
0378:                                    parentContainer.replace(
0379:                                            containerPlaceholder,
0380:                                            (LayoutPart) container);
0381:                                }
0382:                                containerPlaceholder.setRealContainer(null);
0383:                            }
0384:
0385:                            // reparent part.
0386:                            if (!(container instanceof  ViewStack)) {
0387:                                // We don't need to reparent children of PartTabFolders since they will automatically
0388:                                // reparent their children when they become visible. This if statement used to be 
0389:                                // part of an else branch. Investigate if it is still necessary.
0390:                                part.reparent(mainLayout.getParent());
0391:                            }
0392:
0393:                            // see if we should replace the placeholder
0394:                            if (placeholder.hasWildCard()) {
0395:                                if (container instanceof  PartSashContainer) {
0396:                                    ((PartSashContainer) container)
0397:                                            .addChildForPlaceholder(part,
0398:                                                    placeholder);
0399:                                } else {
0400:                                    container.add(part);
0401:                                }
0402:                            } else {
0403:                                container.replace(placeholder, part);
0404:                            }
0405:                        }
0406:                    }
0407:                }
0408:            }
0409:
0410:            /**
0411:             * Attaches a part that was previously detached to the mainLayout. 
0412:             * 
0413:             * @param ref
0414:             */
0415:            public void attachPart(IViewReference ref) {
0416:                ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref)
0417:                        .getPane();
0418:
0419:                // Restore any maximized part before re-attaching.
0420:                // Note that 'getMaximizedStack != null' implies 'useNewMinMax'
0421:                if (getMaximizedStack() != null) {
0422:                    getMaximizedStack().setState(
0423:                            IStackPresentationSite.STATE_RESTORED);
0424:                }
0425:
0426:                derefPart(pane);
0427:                addPart(pane);
0428:                bringPartToTop(pane);
0429:                pane.setFocus();
0430:            }
0431:
0432:            /**
0433:             * Return whether detachable parts can be supported.
0434:             */
0435:            public boolean canDetach() {
0436:                return detachable;
0437:            }
0438:
0439:            /**
0440:             * Bring a part forward so it is visible.
0441:             * 
0442:             * @return true if the part was brought to top, false if not.
0443:             */
0444:            public boolean bringPartToTop(LayoutPart part) {
0445:                ILayoutContainer container = part.getContainer();
0446:                if (container != null && container instanceof  PartStack) {
0447:                    PartStack folder = (PartStack) container;
0448:                    if (folder.getSelection() != part) {
0449:                        folder.setSelection(part);
0450:                        return true;
0451:                    }
0452:                }
0453:                return false;
0454:            }
0455:
0456:            /**
0457:             * Returns true if the given part is visible.
0458:             * A part is visible if it's top-level (not in a tab folder) or if it is the top one 
0459:             * in a tab folder.
0460:             */
0461:            public boolean isPartVisible(IWorkbenchPartReference partRef) {
0462:                LayoutPart foundPart;
0463:                if (partRef instanceof  IViewReference) {
0464:                    foundPart = findPart(partRef.getId(),
0465:                            ((IViewReference) partRef).getSecondaryId());
0466:                } else {
0467:                    foundPart = findPart(partRef.getId());
0468:                }
0469:                if (foundPart == null) {
0470:                    return false;
0471:                }
0472:                if (foundPart instanceof  PartPlaceholder) {
0473:                    return false;
0474:                }
0475:
0476:                ILayoutContainer container = foundPart.getContainer();
0477:
0478:                if (container instanceof  ContainerPlaceholder) {
0479:                    return false;
0480:                }
0481:
0482:                if (container instanceof  ViewStack) {
0483:                    ViewStack folder = (ViewStack) container;
0484:                    PartPane visiblePart = folder.getSelection();
0485:                    if (visiblePart == null) {
0486:                        return false;
0487:                    }
0488:                    return partRef.equals(visiblePart.getPartReference());
0489:                }
0490:                return true;
0491:            }
0492:
0493:            /**
0494:             * Returns true is not in a tab folder or if it is the top one in a tab
0495:             * folder.
0496:             */
0497:            public boolean willPartBeVisible(String partId) {
0498:                return willPartBeVisible(partId, null);
0499:            }
0500:
0501:            public boolean willPartBeVisible(String partId, String secondaryId) {
0502:                LayoutPart part = findPart(partId, secondaryId);
0503:                if (part == null) {
0504:                    return false;
0505:                }
0506:                ILayoutContainer container = part.getContainer();
0507:                if (container != null
0508:                        && container instanceof  ContainerPlaceholder) {
0509:                    container = (ILayoutContainer) ((ContainerPlaceholder) container)
0510:                            .getRealContainer();
0511:                }
0512:
0513:                if (container != null && container instanceof  ViewStack) {
0514:                    ViewStack folder = (ViewStack) container;
0515:                    if (folder.getSelection() == null) {
0516:                        return false;
0517:                    }
0518:                    return part.getCompoundId().equals(
0519:                            folder.getSelection().getCompoundId());
0520:                }
0521:                return true;
0522:            }
0523:
0524:            /**
0525:             * Answer a list of the PartPlaceholder objects.
0526:             */
0527:            private PartPlaceholder[] collectPlaceholders() {
0528:                // Scan the main window.
0529:                PartPlaceholder[] results = collectPlaceholders(mainLayout
0530:                        .getChildren());
0531:
0532:                // Scan each detached window.
0533:                if (detachable) {
0534:                    for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0535:                        DetachedWindow win = (DetachedWindow) detachedWindowList
0536:                                .get(i);
0537:                        PartPlaceholder[] moreResults = collectPlaceholders(win
0538:                                .getChildren());
0539:                        if (moreResults.length > 0) {
0540:                            int newLength = results.length + moreResults.length;
0541:                            PartPlaceholder[] newResults = new PartPlaceholder[newLength];
0542:                            System.arraycopy(results, 0, newResults, 0,
0543:                                    results.length);
0544:                            System.arraycopy(moreResults, 0, newResults,
0545:                                    results.length, moreResults.length);
0546:                            results = newResults;
0547:                        }
0548:                    }
0549:                }
0550:                return results;
0551:            }
0552:
0553:            /**
0554:             * Answer a list of the PartPlaceholder objects.
0555:             */
0556:            private PartPlaceholder[] collectPlaceholders(LayoutPart[] parts) {
0557:                PartPlaceholder[] result = new PartPlaceholder[0];
0558:
0559:                for (int i = 0, length = parts.length; i < length; i++) {
0560:                    LayoutPart part = parts[i];
0561:                    if (part instanceof  ILayoutContainer) {
0562:                        // iterate through sub containers to find sub-parts
0563:                        PartPlaceholder[] newParts = collectPlaceholders(((ILayoutContainer) part)
0564:                                .getChildren());
0565:                        PartPlaceholder[] newResult = new PartPlaceholder[result.length
0566:                                + newParts.length];
0567:                        System
0568:                                .arraycopy(result, 0, newResult, 0,
0569:                                        result.length);
0570:                        System.arraycopy(newParts, 0, newResult, result.length,
0571:                                newParts.length);
0572:                        result = newResult;
0573:                    } else if (part instanceof  PartPlaceholder) {
0574:                        PartPlaceholder[] newResult = new PartPlaceholder[result.length + 1];
0575:                        System
0576:                                .arraycopy(result, 0, newResult, 0,
0577:                                        result.length);
0578:                        newResult[result.length] = (PartPlaceholder) part;
0579:                        result = newResult;
0580:                    }
0581:                }
0582:
0583:                return result;
0584:            }
0585:
0586:            /**
0587:             * Answer a list of the view panes.
0588:             */
0589:            public void collectViewPanes(List result) {
0590:                // Scan the main window.
0591:                collectViewPanes(result, mainLayout.getChildren());
0592:
0593:                // Scan each detached window.
0594:                if (detachable) {
0595:                    for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0596:                        DetachedWindow win = (DetachedWindow) detachedWindowList
0597:                                .get(i);
0598:                        collectViewPanes(result, win.getChildren());
0599:                    }
0600:                }
0601:            }
0602:
0603:            /**
0604:             * Answer a list of the view panes.
0605:             */
0606:            private void collectViewPanes(List result, LayoutPart[] parts) {
0607:                for (int i = 0, length = parts.length; i < length; i++) {
0608:                    LayoutPart part = parts[i];
0609:                    if (part instanceof  ViewPane) {
0610:                        result.add(part);
0611:                    } else if (part instanceof  ILayoutContainer) {
0612:                        collectViewPanes(result, ((ILayoutContainer) part)
0613:                                .getChildren());
0614:                    }
0615:                }
0616:            }
0617:
0618:            /**
0619:             * Hide the presentation.
0620:             */
0621:            public void deactivate() {
0622:                if (!active) {
0623:                    return;
0624:                }
0625:
0626:                disableAllDrag();
0627:
0628:                // Reparent all views to the main window
0629:                Composite parent = mainLayout.getParent();
0630:                Vector children = new Vector();
0631:                collectViewPanes(children, mainLayout.getChildren());
0632:
0633:                for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0634:                    DetachedWindow window = (DetachedWindow) detachedWindowList
0635:                            .get(i);
0636:                    collectViewPanes(children, window.getChildren());
0637:                }
0638:
0639:                // *** Do we even need to do this if detached windows not supported?
0640:                Enumeration itr = children.elements();
0641:                while (itr.hasMoreElements()) {
0642:                    LayoutPart part = (LayoutPart) itr.nextElement();
0643:                    part.reparent(parent);
0644:                }
0645:
0646:                // Dispose main layout.
0647:
0648:                mainLayout.setActive(false);
0649:
0650:                // Dispose the detached windows
0651:                for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0652:                    DetachedWindow window = (DetachedWindow) detachedWindowList
0653:                            .get(i);
0654:                    window.close();
0655:                }
0656:
0657:                active = false;
0658:            }
0659:
0660:            public void dispose() {
0661:                mainLayout.dispose();
0662:                mainLayout.disposeSashes();
0663:            }
0664:
0665:            /**
0666:             * Writes a description of the layout to the given string buffer.
0667:             * This is used for drag-drop test suites to determine if two layouts are the
0668:             * same. Like a hash code, the description should compare as equal iff the
0669:             * layouts are the same. However, it should be user-readable in order to
0670:             * help debug failed tests. Although these are english readable strings,
0671:             * they should not be translated or equality tests will fail.
0672:             * <p>
0673:             * This is only intended for use by test suites.
0674:             * </p>
0675:             * 
0676:             * @param buf
0677:             */
0678:            public void describeLayout(StringBuffer buf) {
0679:
0680:                if (detachable) {
0681:                    if (detachedWindowList.size() != 0) {
0682:                        buf.append("detachedWindows ("); //$NON-NLS-1$
0683:
0684:                        for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
0685:                            DetachedWindow window = (DetachedWindow) detachedWindowList
0686:                                    .get(i);
0687:                            LayoutPart[] children = window.getChildren();
0688:                            if (children.length != 0) {
0689:                                buf.append("dWindow ("); //$NON-NLS-1$
0690:                                for (int j = 0; j < children.length; j++) {
0691:                                    buf.append(((ViewPane) children[j])
0692:                                            .getViewReference().getPartName());
0693:                                    if (j < (children.length - 1)) {
0694:                                        buf.append(", "); //$NON-NLS-1$
0695:                                    }
0696:                                }
0697:                                buf.append(")"); //$NON-NLS-1$
0698:                            }
0699:
0700:                        }
0701:                        buf.append("), "); //$NON-NLS-1$
0702:                    }
0703:                }
0704:
0705:                getLayout().describeLayout(buf);
0706:            }
0707:
0708:            /**
0709:             * Deref a given part. Deconstruct its container as required. Do not remove
0710:             * drag listeners.
0711:             */
0712:            /* package */void derefPart(LayoutPart part) {
0713:                if (part instanceof  ViewPane) {
0714:                    IViewReference ref = ((ViewPane) part).getViewReference();
0715:                    if (perspective.isFastView(ref)) {
0716:                        // Special check: if it's a fast view then it's actual ViewStack
0717:                        // may only contain placeholders and the stack is represented in
0718:                        // the presentation by a container placeholder...make sure the
0719:                        // PartPlaceHolder for 'ref' is removed from the ViewStack
0720:                        String id = perspective.getFastViewManager()
0721:                                .getIdForRef(ref);
0722:                        LayoutPart parentPart = findPart(id, null);
0723:                        if (parentPart instanceof  ContainerPlaceholder) {
0724:                            ViewStack vs = (ViewStack) ((ContainerPlaceholder) parentPart)
0725:                                    .getRealContainer();
0726:                            LayoutPart[] kids = vs.getChildren();
0727:                            for (int i = 0; i < kids.length; i++) {
0728:                                if (kids[i] instanceof  PartPlaceholder) {
0729:                                    if (ref.getId().equals(kids[i].id))
0730:                                        vs.remove(kids[i]);
0731:                                }
0732:                            }
0733:                        }
0734:                        perspective.getFastViewManager().removeViewReference(
0735:                                ref, true, true);
0736:                    }
0737:                }
0738:
0739:                // Get vital part stats before reparenting.
0740:                ILayoutContainer oldContainer = part.getContainer();
0741:                boolean wasDocked = part.isDocked();
0742:                Shell oldShell = part.getShell();
0743:
0744:                // Reparent the part back to the main window
0745:                part.reparent(mainLayout.getParent());
0746:
0747:                // Update container.
0748:                if (oldContainer == null) {
0749:                    return;
0750:                }
0751:
0752:                oldContainer.remove(part);
0753:
0754:                LayoutPart[] children = oldContainer.getChildren();
0755:                if (wasDocked) {
0756:                    boolean hasChildren = (children != null)
0757:                            && (children.length > 0);
0758:                    if (hasChildren) {
0759:                        // make sure one is at least visible
0760:                        int childVisible = 0;
0761:                        for (int i = 0; i < children.length; i++) {
0762:                            if (children[i].getControl() != null) {
0763:                                childVisible++;
0764:                            }
0765:                        }
0766:
0767:                        // none visible, then reprarent and remove container
0768:                        if (oldContainer instanceof  ViewStack) {
0769:                            ViewStack folder = (ViewStack) oldContainer;
0770:
0771:                            // Is the part in the trim?
0772:                            boolean inTrim = false;
0773:                            // Safety check...there may be no FastViewManager
0774:                            if (perspective.getFastViewManager() != null)
0775:                                inTrim = perspective.getFastViewManager()
0776:                                        .getFastViews(folder.getID()).size() > 0;
0777:
0778:                            if (childVisible == 0 && !inTrim) {
0779:                                ILayoutContainer parentContainer = folder
0780:                                        .getContainer();
0781:                                for (int i = 0; i < children.length; i++) {
0782:                                    folder.remove(children[i]);
0783:                                    parentContainer.add(children[i]);
0784:                                }
0785:                                hasChildren = false;
0786:                            } else if (childVisible == 1) {
0787:                                LayoutTree layout = mainLayout.getLayoutTree();
0788:                                layout = layout.find(folder);
0789:                                layout.setBounds(layout.getBounds());
0790:                            }
0791:                        }
0792:                    }
0793:
0794:                    if (!hasChildren) {
0795:                        // There are no more children in this container, so get rid of
0796:                        // it
0797:                        if (oldContainer instanceof  LayoutPart) {
0798:                            LayoutPart parent = (LayoutPart) oldContainer;
0799:                            ILayoutContainer parentContainer = parent
0800:                                    .getContainer();
0801:                            if (parentContainer != null) {
0802:                                parentContainer.remove(parent);
0803:                                parent.dispose();
0804:                            }
0805:                        }
0806:                    }
0807:                } else if (!wasDocked) {
0808:                    if (children == null || children.length == 0) {
0809:                        // There are no more children in this container, so get rid of
0810:                        // it
0811:                        // Turn on redraw again just in case it was off.
0812:                        //oldShell.setRedraw(true);
0813:                        DetachedWindow w = (DetachedWindow) oldShell.getData();
0814:                        oldShell.close();
0815:                        detachedWindowList.remove(w);
0816:                    } else {
0817:                        // There are children. If none are visible hide detached
0818:                        // window.
0819:                        boolean allInvisible = true;
0820:                        for (int i = 0, length = children.length; i < length; i++) {
0821:                            if (!(children[i] instanceof  PartPlaceholder)) {
0822:                                allInvisible = false;
0823:                                break;
0824:                            }
0825:                        }
0826:                        if (allInvisible) {
0827:                            DetachedPlaceHolder placeholder = new DetachedPlaceHolder(
0828:                                    "", //$NON-NLS-1$
0829:                                    oldShell.getBounds());
0830:                            for (int i = 0, length = children.length; i < length; i++) {
0831:                                oldContainer.remove(children[i]);
0832:                                children[i].setContainer(placeholder);
0833:                                placeholder.add(children[i]);
0834:                            }
0835:                            detachedPlaceHolderList.add(placeholder);
0836:                            DetachedWindow w = (DetachedWindow) oldShell
0837:                                    .getData();
0838:                            oldShell.close();
0839:                            detachedWindowList.remove(w);
0840:                        }
0841:                    }
0842:                }
0843:
0844:            }
0845:
0846:            /**
0847:             * Create a detached window containing a part.
0848:             */
0849:            private void detach(LayoutPart source, int x, int y) {
0850:
0851:                // Detaching is disabled on some platforms ..
0852:                if (!detachable) {
0853:                    return;
0854:                }
0855:
0856:                LayoutPart part = source.getPart();
0857:                // Calculate detached window size.
0858:                Point size = part.getSize();
0859:                if (size.x == 0 || size.y == 0) {
0860:                    ILayoutContainer container = part.getContainer();
0861:                    if (container instanceof  LayoutPart) {
0862:                        size = ((LayoutPart) container).getSize();
0863:                    }
0864:                }
0865:                int width = Math.max(size.x, MIN_DETACH_WIDTH);
0866:                int height = Math.max(size.y, MIN_DETACH_HEIGHT);
0867:
0868:                // Create detached window.
0869:                DetachedWindow window = new DetachedWindow(page);
0870:                detachedWindowList.add(window);
0871:
0872:                // Open window.
0873:                window.create();
0874:                window.getShell().setBounds(x, y, width, height);
0875:                window.open();
0876:
0877:                if (part instanceof  ViewStack) {
0878:                    window.getShell().setRedraw(false);
0879:                    parentWidget.setRedraw(false);
0880:                    LayoutPart visiblePart = ((ViewStack) part).getSelection();
0881:                    LayoutPart children[] = ((ViewStack) part).getChildren();
0882:                    for (int i = 0; i < children.length; i++) {
0883:                        if (children[i] instanceof  ViewPane) {
0884:                            // remove the part from its current container
0885:                            derefPart(children[i]);
0886:                            // add part to detached window.
0887:                            ViewPane pane = (ViewPane) children[i];
0888:                            window.add(pane);
0889:                        }
0890:                    }
0891:                    if (visiblePart != null) {
0892:                        bringPartToTop(visiblePart);
0893:                        visiblePart.setFocus();
0894:                    }
0895:                    window.getShell().setRedraw(true);
0896:                    parentWidget.setRedraw(true);
0897:                } else {
0898:                    // remove the part from its current container
0899:                    derefPart(part);
0900:                    // add part to detached window.
0901:                    ViewPane pane = (ViewPane) part;
0902:                    window.add(pane);
0903:                    part.setFocus();
0904:                }
0905:
0906:            }
0907:
0908:            /**
0909:             * Detached a part from the mainLayout. Presently this does not use placeholders
0910:             * since the current implementation is not robust enough to remember a view's position
0911:             * in more than one root container. For now the view is simply derefed and will dock
0912:             * in the default position when attachPart is called. 
0913:             * 
0914:             * By default parts detached this way are set to float on top of the workbench
0915:             * without docking. It is assumed that people that want to drag a part back onto
0916:             * the WorkbenchWindow will detach it via drag and drop. 
0917:             * 
0918:             * @param ref
0919:             */
0920:            public void detachPart(IViewReference ref) {
0921:                ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref)
0922:                        .getPane();
0923:                if (canDetach() && pane != null) {
0924:                    Rectangle bounds = pane.getParentBounds();
0925:                    detach(pane, bounds.x, bounds.y);
0926:                }
0927:            }
0928:
0929:            /**
0930:             * Create a detached window containing a part.
0931:             */
0932:            public void addDetachedPart(LayoutPart part) {
0933:                // Calculate detached window size.
0934:                Rectangle bounds = parentWidget.getShell().getBounds();
0935:                bounds.x = bounds.x + (bounds.width - 300) / 2;
0936:                bounds.y = bounds.y + (bounds.height - 300) / 2;
0937:
0938:                addDetachedPart(part, bounds);
0939:            }
0940:
0941:            public void addDetachedPart(LayoutPart part, Rectangle bounds) {
0942:                // Detaching is disabled on some platforms ..
0943:                if (!detachable) {
0944:                    addPart(part);
0945:                    return;
0946:                }
0947:
0948:                // Create detached window.
0949:                DetachedWindow window = new DetachedWindow(page);
0950:                detachedWindowList.add(window);
0951:                window.create();
0952:
0953:                // add part to detached window.
0954:                part.createControl(window.getShell());
0955:                ViewPane pane = (ViewPane) part;
0956:                window.add(pane);
0957:
0958:                // Open window.
0959:                window.getShell().setBounds(bounds.x, bounds.y, bounds.width,
0960:                        bounds.height);
0961:                window.open();
0962:
0963:                part.setFocus();
0964:
0965:            }
0966:
0967:            /**
0968:             * disableDragging.
0969:             */
0970:            private void disableAllDrag() {
0971:                DragUtil.removeDragTarget(null, dragTarget);
0972:            }
0973:
0974:            /**
0975:             * enableDragging.
0976:             */
0977:            private void enableAllDrag() {
0978:                DragUtil.addDragTarget(null, dragTarget);
0979:            }
0980:
0981:            /**
0982:             * Find the first part with a given ID in the presentation.
0983:             * Wild cards now supported.
0984:             */
0985:            private LayoutPart findPart(String id) {
0986:                return findPart(id, null);
0987:            }
0988:
0989:            /**
0990:             * Find the first part that matches the specified 
0991:             * primary and secondary id pair.  Wild cards
0992:             * are supported.
0993:             */
0994:            public LayoutPart findPart(String primaryId, String secondaryId) {
0995:                // check main window.
0996:                ArrayList matchingParts = new ArrayList();
0997:                LayoutPart part = (secondaryId != null) ? findPart(primaryId,
0998:                        secondaryId, mainLayout.getChildren(), matchingParts)
0999:                        : findPart(primaryId, mainLayout.getChildren(),
1000:                                matchingParts);
1001:                if (part != null) {
1002:                    return part;
1003:                }
1004:
1005:                // check each detached windows.
1006:                for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
1007:                    DetachedWindow window = (DetachedWindow) detachedWindowList
1008:                            .get(i);
1009:                    part = (secondaryId != null) ? findPart(primaryId,
1010:                            secondaryId, window.getChildren(), matchingParts)
1011:                            : findPart(primaryId, window.getChildren(),
1012:                                    matchingParts);
1013:                    if (part != null) {
1014:                        return part;
1015:                    }
1016:                }
1017:                for (int i = 0; i < detachedPlaceHolderList.size(); i++) {
1018:                    DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList
1019:                            .get(i);
1020:                    part = (secondaryId != null) ? findPart(primaryId,
1021:                            secondaryId, holder.getChildren(), matchingParts)
1022:                            : findPart(primaryId, holder.getChildren(),
1023:                                    matchingParts);
1024:                    if (part != null) {
1025:                        return part;
1026:                    }
1027:                }
1028:
1029:                // sort the matching parts
1030:                if (matchingParts.size() > 0) {
1031:                    Collections.sort(matchingParts);
1032:                    MatchingPart mostSignificantPart = (MatchingPart) matchingParts
1033:                            .get(0);
1034:                    if (mostSignificantPart != null) {
1035:                        return mostSignificantPart.part;
1036:                    }
1037:                }
1038:
1039:                // Not found.
1040:                return null;
1041:            }
1042:
1043:            /**
1044:             * Find the first part with a given ID in the presentation.
1045:             */
1046:            private LayoutPart findPart(String id, LayoutPart[] parts,
1047:                    ArrayList matchingParts) {
1048:                for (int i = 0, length = parts.length; i < length; i++) {
1049:                    LayoutPart part = parts[i];
1050:                    // check for part equality, parts with secondary ids fail
1051:                    if (part.getID().equals(id)) {
1052:                        if (part instanceof  ViewPane) {
1053:                            ViewPane pane = (ViewPane) part;
1054:                            IViewReference ref = (IViewReference) pane
1055:                                    .getPartReference();
1056:                            if (ref.getSecondaryId() != null) {
1057:                                continue;
1058:                            }
1059:                        }
1060:                        return part;
1061:                    }
1062:                    // check pattern matching placeholders
1063:                    else if (part instanceof  PartPlaceholder
1064:                            && ((PartPlaceholder) part).hasWildCard()) {
1065:                        StringMatcher sm = new StringMatcher(part.getID(),
1066:                                true, false);
1067:                        if (sm.match(id)) {
1068:                            matchingParts.add(new MatchingPart(part.getID(),
1069:                                    null, part));
1070:                        }
1071:                    } else if (part instanceof  EditorSashContainer) {
1072:                        // Skip.
1073:                    } else if (part instanceof  ILayoutContainer) {
1074:                        part = findPart(id, ((ILayoutContainer) part)
1075:                                .getChildren(), matchingParts);
1076:                        if (part != null) {
1077:                            return part;
1078:                        }
1079:                    }
1080:                }
1081:                return null;
1082:            }
1083:
1084:            /**
1085:             * Find the first part that matches the specified 
1086:             * primary and secondary id pair.  Wild cards
1087:             * are supported.
1088:             */
1089:            private LayoutPart findPart(String primaryId, String secondaryId,
1090:                    LayoutPart[] parts, ArrayList matchingParts) {
1091:                for (int i = 0, length = parts.length; i < length; i++) {
1092:                    LayoutPart part = parts[i];
1093:                    // check containers first
1094:                    if (part instanceof  ILayoutContainer) {
1095:                        LayoutPart testPart = findPart(primaryId, secondaryId,
1096:                                ((ILayoutContainer) part).getChildren(),
1097:                                matchingParts);
1098:                        if (testPart != null) {
1099:                            return testPart;
1100:                        }
1101:                    }
1102:                    // check for view part equality
1103:                    if (part instanceof  ViewPane) {
1104:                        ViewPane pane = (ViewPane) part;
1105:                        IViewReference ref = (IViewReference) pane
1106:                                .getPartReference();
1107:                        if (ref.getId().equals(primaryId)
1108:                                && ref.getSecondaryId() != null
1109:                                && ref.getSecondaryId().equals(secondaryId)) {
1110:                            return part;
1111:                        }
1112:                    }
1113:                    // check placeholders
1114:                    else if ((parts[i] instanceof  PartPlaceholder)) {
1115:                        String id = part.getID();
1116:
1117:                        // optimization: don't bother parsing id if it has no separator -- it can't match
1118:                        String phSecondaryId = ViewFactory
1119:                                .extractSecondaryId(id);
1120:                        if (phSecondaryId == null) {
1121:                            // but still need to check for wildcard case
1122:                            if (id.equals(PartPlaceholder.WILD_CARD)) {
1123:                                matchingParts.add(new MatchingPart(id, null,
1124:                                        part));
1125:                            }
1126:                            continue;
1127:                        }
1128:
1129:                        String phPrimaryId = ViewFactory.extractPrimaryId(id);
1130:                        // perfect matching pair
1131:                        if (phPrimaryId.equals(primaryId)
1132:                                && phSecondaryId.equals(secondaryId)) {
1133:                            return part;
1134:                        }
1135:                        // check for partial matching pair
1136:                        StringMatcher sm = new StringMatcher(phPrimaryId, true,
1137:                                false);
1138:                        if (sm.match(primaryId)) {
1139:                            sm = new StringMatcher(phSecondaryId, true, false);
1140:                            if (sm.match(secondaryId)) {
1141:                                matchingParts.add(new MatchingPart(phPrimaryId,
1142:                                        phSecondaryId, part));
1143:                            }
1144:                        }
1145:                    } else if (part instanceof  EditorSashContainer) {
1146:                        // Skip.
1147:                    }
1148:                }
1149:                return null;
1150:            }
1151:
1152:            /**
1153:             * Returns true if a placeholder exists for a given ID.
1154:             */
1155:            public boolean hasPlaceholder(String id) {
1156:                return hasPlaceholder(id, null);
1157:            }
1158:
1159:            /**
1160:             * Returns true if a placeholder exists for a given ID.
1161:             * @since 3.0
1162:             */
1163:            public boolean hasPlaceholder(String primaryId, String secondaryId) {
1164:                LayoutPart testPart;
1165:                if (secondaryId == null) {
1166:                    testPart = findPart(primaryId);
1167:                } else {
1168:                    testPart = findPart(primaryId, secondaryId);
1169:                }
1170:                return (testPart != null && testPart instanceof  PartPlaceholder);
1171:            }
1172:
1173:            /**
1174:             * Returns the layout container.
1175:             */
1176:            public ViewSashContainer getLayout() {
1177:                return mainLayout;
1178:            }
1179:
1180:            /**
1181:             * Gets the active state.
1182:             */
1183:            public boolean isActive() {
1184:                return active;
1185:            }
1186:
1187:            /**
1188:             * Returns whether the presentation is zoomed.
1189:             * 
1190:             * <strong>NOTE:</strong> As of 3.3 this method should always return 'false'
1191:             * when using the new min/max behavior. It is only used for
1192:             * legacy 'zoom' handling.
1193:             */
1194:            public boolean isZoomed() {
1195:                return mainLayout.getZoomedPart() != null;
1196:            }
1197:
1198:            /**
1199:             * @return The currently maxmized stack (if any)
1200:             */
1201:            public PartStack getMaximizedStack() {
1202:                return maximizedStack;
1203:            }
1204:
1205:            /**
1206:             * Sets the currently maximized stack. Used for query
1207:             * and 'unZoom' purposes in the 3.3 presentation.
1208:             * 
1209:             * @param stack The newly maximized stack
1210:             */
1211:            public void setMaximizedStack(PartStack stack) {
1212:                if (stack == maximizedStack)
1213:                    return;
1214:
1215:                maximizedStack = stack;
1216:            }
1217:
1218:            /**
1219:             * Returns the ratio that should be used when docking the given source
1220:             * part onto the given target
1221:             * 
1222:             * @param source newly added part
1223:             * @param target existing part being dragged over
1224:             * @return the final size of the source part (wrt the current size of target)
1225:             * after it is docked
1226:             */
1227:            public static float getDockingRatio(LayoutPart source,
1228:                    LayoutPart target) {
1229:                if ((source instanceof  ViewPane || source instanceof  ViewStack)
1230:                        && target instanceof  EditorSashContainer) {
1231:                    return 0.25f;
1232:                }
1233:                return 0.5f;
1234:            }
1235:
1236:            /**
1237:             * Returns whether changes to a part will affect zoom. There are a few
1238:             * conditions for this .. - we are zoomed. - the part is contained in the
1239:             * main window. - the part is not the zoom part - the part is not a fast
1240:             * view - the part and the zoom part are not in the same editor workbook
1241:             * - the part and the zoom part are not in the same view stack.
1242:             */
1243:            public boolean partChangeAffectsZoom(LayoutPart pane) {
1244:                return pane.isObscuredByZoom();
1245:            }
1246:
1247:            /**
1248:             * Remove all references to a part.
1249:             */
1250:            public void removePart(LayoutPart part) {
1251:
1252:                // Reparent the part back to the main window
1253:                Composite parent = mainLayout.getParent();
1254:                part.reparent(parent);
1255:
1256:                // Replace part with a placeholder
1257:                ILayoutContainer container = part.getContainer();
1258:                if (container != null) {
1259:                    String placeHolderId = part.getPlaceHolderId();
1260:                    container.replace(part, new PartPlaceholder(placeHolderId));
1261:
1262:                    // If the parent is root we're done. Do not try to replace
1263:                    // it with placeholder.
1264:                    if (container == mainLayout) {
1265:                        return;
1266:                    }
1267:
1268:                    // If the parent is empty replace it with a placeholder.
1269:                    LayoutPart[] children = container.getChildren();
1270:                    if (children != null) {
1271:                        boolean allInvisible = true;
1272:                        for (int i = 0, length = children.length; i < length; i++) {
1273:                            if (!(children[i] instanceof  PartPlaceholder)) {
1274:                                allInvisible = false;
1275:                                break;
1276:                            }
1277:                        }
1278:                        if (allInvisible && (container instanceof  LayoutPart)) {
1279:                            // what type of window are we in?
1280:                            LayoutPart cPart = (LayoutPart) container;
1281:                            //Window oldWindow = cPart.getWindow();
1282:                            boolean wasDocked = cPart.isDocked();
1283:                            Shell oldShell = cPart.getShell();
1284:                            if (wasDocked) {
1285:
1286:                                // PR 1GDFVBY: ViewStack not disposed when page
1287:                                // closed.
1288:                                if (container instanceof  ViewStack) {
1289:                                    ((ViewStack) container).dispose();
1290:                                }
1291:
1292:                                // replace the real container with a
1293:                                // ContainerPlaceholder
1294:                                ILayoutContainer parentContainer = cPart
1295:                                        .getContainer();
1296:                                ContainerPlaceholder placeholder = new ContainerPlaceholder(
1297:                                        cPart.getID());
1298:                                placeholder.setRealContainer(container);
1299:                                parentContainer.replace(cPart, placeholder);
1300:
1301:                            } else {
1302:                                DetachedPlaceHolder placeholder = new DetachedPlaceHolder(
1303:                                        "", oldShell.getBounds()); //$NON-NLS-1$
1304:                                for (int i = 0, length = children.length; i < length; i++) {
1305:                                    children[i].getContainer().remove(
1306:                                            children[i]);
1307:                                    children[i].setContainer(placeholder);
1308:                                    placeholder.add(children[i]);
1309:                                }
1310:                                detachedPlaceHolderList.add(placeholder);
1311:                                DetachedWindow w = (DetachedWindow) oldShell
1312:                                        .getData();
1313:                                oldShell.close();
1314:                                detachedWindowList.remove(w);
1315:                            }
1316:                        }
1317:                    }
1318:                }
1319:            }
1320:
1321:            /**
1322:             * Add a part to the presentation.
1323:             * 
1324:             * Note: unlike all other LayoutParts, PartPlaceholders will still point to
1325:             * their parent container even when it is inactive. This method relies on this
1326:             * fact to locate the parent.
1327:             */
1328:            public void replacePlaceholderWithPart(LayoutPart part) {
1329:
1330:                // Look for a PartPlaceholder that will tell us how to position this
1331:                // object
1332:                PartPlaceholder[] placeholders = collectPlaceholders();
1333:                for (int i = 0, length = placeholders.length; i < length; i++) {
1334:                    if (placeholders[i].getCompoundId().equals(
1335:                            part.getCompoundId())) {
1336:                        // found a matching placeholder which we can replace with the
1337:                        // new View
1338:                        ILayoutContainer container = placeholders[i]
1339:                                .getContainer();
1340:                        if (container != null) {
1341:                            if (container instanceof  ContainerPlaceholder) {
1342:                                // One of the children is now visible so replace the
1343:                                // ContainerPlaceholder with the real container
1344:                                ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container;
1345:                                ILayoutContainer parentContainer = containerPlaceholder
1346:                                        .getContainer();
1347:                                container = (ILayoutContainer) containerPlaceholder
1348:                                        .getRealContainer();
1349:                                if (container instanceof  LayoutPart) {
1350:                                    parentContainer.replace(
1351:                                            containerPlaceholder,
1352:                                            (LayoutPart) container);
1353:                                }
1354:                                containerPlaceholder.setRealContainer(null);
1355:                            }
1356:                            container.replace(placeholders[i], part);
1357:                            return;
1358:                        }
1359:                    }
1360:                }
1361:
1362:            }
1363:
1364:            /**
1365:             * @see org.eclipse.ui.IPersistable
1366:             */
1367:            public IStatus restoreState(IMemento memento) {
1368:                // Restore main window.
1369:                IMemento childMem = memento
1370:                        .getChild(IWorkbenchConstants.TAG_MAIN_WINDOW);
1371:                IStatus r = mainLayout.restoreState(childMem);
1372:
1373:                // Restore each floating window.
1374:                if (detachable) {
1375:                    IMemento detachedWindows[] = memento
1376:                            .getChildren(IWorkbenchConstants.TAG_DETACHED_WINDOW);
1377:                    for (int nX = 0; nX < detachedWindows.length; nX++) {
1378:                        DetachedWindow win = new DetachedWindow(page);
1379:                        detachedWindowList.add(win);
1380:                        win.restoreState(detachedWindows[nX]);
1381:                    }
1382:                    IMemento childrenMem[] = memento
1383:                            .getChildren(IWorkbenchConstants.TAG_HIDDEN_WINDOW);
1384:                    for (int i = 0, length = childrenMem.length; i < length; i++) {
1385:                        DetachedPlaceHolder holder = new DetachedPlaceHolder(
1386:                                "", new Rectangle(0, 0, 0, 0)); //$NON-NLS-1$
1387:                        holder.restoreState(childrenMem[i]);
1388:                        detachedPlaceHolderList.add(holder);
1389:                    }
1390:                }
1391:
1392:                // Get the cached id of the currently maximized stack
1393:                maximizedStackId = childMem
1394:                        .getString(IWorkbenchConstants.TAG_MAXIMIZED);
1395:
1396:                return r;
1397:            }
1398:
1399:            /**
1400:             * @see org.eclipse.ui.IPersistable
1401:             */
1402:            public IStatus saveState(IMemento memento) {
1403:                // Persist main window.
1404:                IMemento childMem = memento
1405:                        .createChild(IWorkbenchConstants.TAG_MAIN_WINDOW);
1406:                IStatus r = mainLayout.saveState(childMem);
1407:
1408:                if (detachable) {
1409:                    // Persist each detached window.
1410:                    for (int i = 0, length = detachedWindowList.size(); i < length; i++) {
1411:                        DetachedWindow window = (DetachedWindow) detachedWindowList
1412:                                .get(i);
1413:                        childMem = memento
1414:                                .createChild(IWorkbenchConstants.TAG_DETACHED_WINDOW);
1415:                        window.saveState(childMem);
1416:                    }
1417:                    for (int i = 0, length = detachedPlaceHolderList.size(); i < length; i++) {
1418:                        DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList
1419:                                .get(i);
1420:                        childMem = memento
1421:                                .createChild(IWorkbenchConstants.TAG_HIDDEN_WINDOW);
1422:                        holder.saveState(childMem);
1423:                    }
1424:                }
1425:
1426:                // Write out the id of the maximized (View) stack (if any)
1427:                // NOTE: we only write this out if it's a ViewStack since the
1428:                // Editor Area is handled by the perspective
1429:                if (maximizedStack instanceof  ViewStack) {
1430:                    childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED,
1431:                            maximizedStack.getID());
1432:                } else if (maximizedStackId != null) {
1433:                    // Maintain the cache if the perspective has never been activated
1434:                    childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED,
1435:                            maximizedStackId);
1436:                }
1437:
1438:                return r;
1439:            }
1440:
1441:            /**
1442:             * Zoom in on a particular layout part.
1443:             */
1444:            public void zoomIn(IWorkbenchPartReference ref) {
1445:                PartPane pane = ((WorkbenchPartReference) ref).getPane();
1446:
1447:                parentWidget.setRedraw(false);
1448:                try {
1449:                    pane.requestZoomIn();
1450:                } finally {
1451:                    parentWidget.setRedraw(true);
1452:                }
1453:            }
1454:
1455:            /**
1456:             * Zoom out.
1457:             */
1458:            public void zoomOut() {
1459:                // New 3.3 behavior
1460:                if (Perspective.useNewMinMax(perspective)) {
1461:                    if (maximizedStack != null)
1462:                        maximizedStack
1463:                                .setState(IStackPresentationSite.STATE_RESTORED);
1464:                    return;
1465:                }
1466:
1467:                LayoutPart zoomPart = mainLayout.getZoomedPart();
1468:                if (zoomPart != null) {
1469:                    zoomPart.requestZoomOut();
1470:                }
1471:            }
1472:
1473:            /**
1474:             * Forces the perspective to have no zoomed or minimized parts.
1475:             * This is used when switching to the 3.3 presentation...
1476:             */
1477:            public void forceNoZoom() {
1478:                // Ensure that nobody's zoomed
1479:                zoomOut();
1480:
1481:                // Now, walk the layout ensuring that nothing is minimized
1482:                LayoutPart[] kids = mainLayout.getChildren();
1483:                for (int i = 0; i < kids.length; i++) {
1484:                    if (kids[i] instanceof  ViewStack) {
1485:                        ((ViewStack) kids[i]).setMinimized(false);
1486:                    } else if (kids[i] instanceof  EditorSashContainer) {
1487:                        LayoutPart[] editorStacks = ((EditorSashContainer) kids[i])
1488:                                .getChildren();
1489:                        for (int j = 0; j < editorStacks.length; j++) {
1490:                            if (editorStacks[j] instanceof  EditorStack) {
1491:                                ((EditorStack) editorStacks[j])
1492:                                        .setMinimized(false);
1493:                            }
1494:                        }
1495:                    }
1496:                }
1497:            }
1498:
1499:            /**
1500:             * Captures the current bounds of all ViewStacks and the editor
1501:             * area and puts them into an ID -> Rectangle map. This info is
1502:             * used to cache the bounds so that we can correctly place minimized
1503:             * stacks during a 'maximized' operation (where the iterative min's
1504:             * affect the current layout while being performed.
1505:             */
1506:            public void updateBoundsMap() {
1507:                boundsMap.clear();
1508:
1509:                // Walk the layout gathering the current bounds of each stack
1510:                // and the editor area
1511:                LayoutPart[] kids = mainLayout.getChildren();
1512:                for (int i = 0; i < kids.length; i++) {
1513:                    if (kids[i] instanceof  ViewStack) {
1514:                        ViewStack vs = (ViewStack) kids[i];
1515:                        boundsMap.put(vs.getID(), vs.getBounds());
1516:                    } else if (kids[i] instanceof  EditorSashContainer) {
1517:                        EditorSashContainer esc = (EditorSashContainer) kids[i];
1518:                        boundsMap.put(esc.getID(), esc.getBounds());
1519:                    }
1520:                }
1521:            }
1522:
1523:            /**
1524:             * Resets the bounds map so that it won't interfere with normal minimize
1525:             * operayions
1526:             */
1527:            public void resetBoundsMap() {
1528:                boundsMap.clear();
1529:            }
1530:
1531:            public Rectangle getCachedBoundsFor(String id) {
1532:                return (Rectangle) boundsMap.get(id);
1533:            }
1534:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.