0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.core.windows;
0043:
0044: import java.awt.*;
0045: import java.beans.*;
0046: import java.net.URL;
0047: import java.util.*;
0048: import java.util.logging.Level;
0049: import java.util.logging.Logger;
0050: import javax.swing.*;
0051: import org.netbeans.core.windows.actions.ActionUtils;
0052: import org.netbeans.core.windows.persistence.PersistenceManager;
0053: import org.openide.nodes.Node;
0054: import org.openide.util.*;
0055: import org.openide.windows.*;
0056:
0057: /**
0058: * This class extends WindowManager to provide all window system functionality.
0059: *
0060: * This class is final only for performance reasons. Can be freely
0061: * unfinaled if desired.
0062: *
0063: * @author Peter Zavadsky
0064: */
0065: public final class WindowManagerImpl extends WindowManager implements
0066: Workspace {
0067: // XXX Implements Workspace for backward compatibility of old API only,
0068: // there are no workspaces any more.
0069:
0070: // XXX PENDING additional, not-yet officialy supported properties.
0071: /** Name of property change fired when active mode changed. */
0072: public static final String PROP_ACTIVE_MODE = "activeMode"; // NOI8N
0073: /** Name of property change fired when maximized mode changed. */
0074: public static final String PROP_MAXIMIZED_MODE = "maximizedMode"; // NOI18N
0075: /** Name of property change fired when editor area state changed. */
0076: public static final String PROP_EDITOR_AREA_STATE = "editorAreaState"; // NOI18N
0077:
0078: /** Init lock. */
0079: private static final Object LOCK_INIT = new Object();
0080:
0081: /** The only instance of the window manager implementation in the system */
0082: private static WindowManagerImpl defaultInstance;
0083:
0084: /** Central unit of window system. */
0085: private final Central central = new Central();
0086:
0087: /** properties support */
0088: private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(
0089: this );
0090:
0091: // PENDING
0092: /** Manages list of recently activated <code>TopCompoennt</code>s. */
0093: private final RecentViewList recentViewList = new RecentViewList(
0094: this );
0095:
0096: /** Only for hack 40237, to not call componentShowing twice */
0097: private TopComponent persistenceShowingTC;
0098:
0099: /** exclusive invocation of runnables */
0100: private Exclusive exclusive = new Exclusive();
0101:
0102: /** Default constructor. Don't use directly, use getDefault()
0103: * instead.
0104: */
0105: public WindowManagerImpl() {
0106: synchronized (LOCK_INIT) {
0107: // a static object to synchronize on
0108: if (defaultInstance != null) {
0109: throw new IllegalStateException(
0110: "Instance already exists"); // NOI18N
0111: }
0112: defaultInstance = this ;
0113: }
0114: }
0115:
0116: /** Singleton accessor, returns instance of window manager implementation */
0117: public static WindowManagerImpl getInstance() {
0118: if (defaultInstance != null) {
0119: // Save a bunch of time accessing global lookup, acc. to profiler.
0120: return defaultInstance;
0121: }
0122: return (WindowManagerImpl) Lookup.getDefault().lookup(
0123: WindowManager.class);
0124: }
0125:
0126: @Override
0127: public void topComponentRequestAttention(TopComponent tc) {
0128: ModeImpl mode = (ModeImpl) findMode(tc);
0129:
0130: central.topComponentRequestAttention(mode, tc);
0131: }
0132:
0133: @Override
0134: public void topComponentCancelRequestAttention(TopComponent tc) {
0135: ModeImpl mode = (ModeImpl) findMode(tc);
0136:
0137: central.topComponentCancelRequestAttention(mode, tc);
0138: }
0139:
0140: /////////////////////////
0141: // API impelementation >>
0142: /////////////////////////
0143:
0144: // PENDING revise this method, it is dangerous to expose the GUI.
0145: /** Provides access to the MainWindow of the IDE.
0146: * Implements <code>WindowManager</code> abstract method.
0147: * @return the MainWindow */
0148: public Frame getMainWindow() {
0149: assertEventDispatchThreadWeak();
0150:
0151: return central.getMainWindow();
0152: }
0153:
0154: /** Called after a current LookAndFeel change to update the IDE's UI
0155: * Implements <code>WindowManager</code> abstract method. */
0156: public void updateUI() {
0157: assertEventDispatchThreadWeak();
0158:
0159: central.updateUI();
0160: }
0161:
0162: /** Creates a component manager for given top component.
0163: * Implements <code>WindowManager</code> abstract method.
0164: * @param c the component
0165: * @return the manager that handles opening, closing and selecting a component
0166: * @deprecated Don't use this. */
0167: protected synchronized WindowManager.Component createTopComponentManager(
0168: TopComponent c) {
0169: assertEventDispatchThreadWeak();
0170:
0171: return null;
0172: }
0173:
0174: /** Creates new workspace with given name and display name.
0175: * Implements <code>WindowManager</code> abstract method.
0176: * @return fake implementation of only workspace
0177: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0178: public Workspace createWorkspace(String name, String displayName) {
0179: assertEventDispatchThreadWeak();
0180:
0181: // get back fake workspace.
0182: return this ;
0183: }
0184:
0185: /** Finds workspace given its name.
0186: * @return fake implementation of only workspace
0187: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0188: public Workspace findWorkspace(String name) {
0189: assertEventDispatchThreadWeak();
0190:
0191: // PENDING what to return?
0192: return this ;
0193: }
0194:
0195: /** List of all currenty available workspaces.
0196: * Implements <code>WindowManager</code> abstract method.
0197: * @return array with only one (fake) workspace impl
0198: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0199: public Workspace[] getWorkspaces() {
0200: assertEventDispatchThreadWeak();
0201:
0202: return new Workspace[] { this };
0203: }
0204:
0205: /** Sets new workspaces.
0206: * Implements <code>WindowManager</code> abstract method.
0207: * @param workspaces array of new workspaces
0208: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0209: public void setWorkspaces(Workspace[] workspaces) {
0210: assertEventDispatchThreadWeak();
0211: }
0212:
0213: /** Gets current workspace. Can be changed by calling Workspace.activate ()
0214: * Implements <code>WindowManager</code> abstract method.
0215: * @return fake implementation of only workspace
0216: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0217: public Workspace getCurrentWorkspace() {
0218: assertEventDispatchThreadWeak();
0219:
0220: // Gets back this as a fake workspace.
0221: return this ;
0222: }
0223:
0224: /** Finds TopComponentGroup of given name. */
0225: public TopComponentGroup findTopComponentGroup(String name) {
0226: assertEventDispatchThread();
0227:
0228: for (Iterator it = getTopComponentGroups().iterator(); it
0229: .hasNext();) {
0230: TopComponentGroupImpl group = (TopComponentGroupImpl) it
0231: .next();
0232: if (group.getName().equals(name)) {
0233: return group;
0234: }
0235: }
0236:
0237: return null;
0238: }
0239:
0240: /** Returns <code>TopComponent</code> for given unique ID.
0241: * @param tcID unique <code>TopComponent</code> ID
0242: * @return <code>TopComponent</code> instance corresponding to unique ID
0243: */
0244: public TopComponent findTopComponent(String tcID) {
0245: assertEventDispatchThreadWeak();
0246:
0247: return getTopComponentForID(tcID);
0248: }
0249:
0250: /** Adds listener.
0251: * Implements <code>WindowManager</code> abstract method. */
0252: public void addPropertyChangeListener(PropertyChangeListener l) {
0253: changeSupport.addPropertyChangeListener(l);
0254: }
0255:
0256: /** Removes listener.
0257: * Implements <code>WindowManager</code> abstract method. */
0258: public void removePropertyChangeListener(PropertyChangeListener l) {
0259: changeSupport.removePropertyChangeListener(l);
0260: }
0261:
0262: ////////////////////////
0263: // API implementation <<
0264: ////////////////////////
0265:
0266: // /** Activates <code>TopComponent</code>, if it is opened. */
0267: // private boolean activateTopComponent(TopComponent tc) {
0268: // if(tc != null) {
0269: // // Find whether the component is in mode.
0270: // ModeImpl mode = (ModeImpl)findMode(tc);
0271: // if(mode != null) {
0272: // // Actually activates the TopComponent.
0273: // central.activateModeTopComponent(mode, tc);
0274: // } else {
0275: // // TopComponent not in mode yet.
0276: // return false;
0277: // }
0278: // }
0279: //
0280: // return true;
0281: // }
0282:
0283: // /** Selects <code>TopComponent</code>, if it is opened. */
0284: // protected void selectTopComponentImpl(TopComponent tc) {
0285: // if(tc != null) {
0286: // // Find whether the component is in mode.
0287: // ModeImpl mode = (ModeImpl)findMode(tc);
0288: // if(mode != null) {
0289: // // Actually select the TopComponent.
0290: // central.setModeSelectedTopComponent(mode, tc);
0291: // }
0292: // }
0293: // }
0294:
0295: // XXX For backward compatibility (Workspace class), this is the only (fake) workspace.
0296: // There are not supported workspaces any more.
0297: ///////////////////////////////////////
0298: // Start of Workspace implementation>>
0299: ///////////////////////////////////////
0300:
0301: /** Gets the programmatic unique name of this workspace.
0302: * Implements <code>Workspace</code> interface method.
0303: * @return the programmatic name of only workspace impl
0304: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0305: public String getName() {
0306: return "FakeWorkspace"; // NOI18N
0307: }
0308:
0309: /** Gets human-presentable name of the workspace.
0310: * Implements <code>Workspace</code> interface method.
0311: * @return the diplay name of the workspace
0312: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0313: public String getDisplayName() {
0314: return NbBundle.getMessage(WindowManagerImpl.class,
0315: "LBL_FakeWorkspace");
0316: }
0317:
0318: /** Gets <code>Set</code> of all <code>Mode</code>'s.
0319: * Implements <code>Workspace</code> interface method. */
0320: public Set<? extends ModeImpl> getModes() {
0321: return central.getModes();
0322: }
0323:
0324: /** Get bounds.
0325: * Implements <code>Workspace</code> interface method. */
0326: public Rectangle getBounds() {
0327: if (getEditorAreaState() == Constants.EDITOR_AREA_JOINED) {
0328: return getMainWindowBoundsJoined();
0329: } else {
0330: return getMainWindowBoundsSeparated();
0331: }
0332: }
0333:
0334: /** Activates this workspace to be current one.
0335: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0336: public void activate() {
0337: }
0338:
0339: /** Creates new <code>Mode</code>.
0340: * Implements <code>Workspace</code> interface method.
0341: * @param name a unique programmatic name of the mode
0342: * @param displayName <em>ignored</em> doesn't have a sense now
0343: * @param icon <em>ignored</em> doesn't have a sense now
0344: * @return the new mode */
0345: public Mode createMode(String name, String displayName, URL icon) {
0346: if (getEditorAreaState() == Constants.EDITOR_AREA_JOINED) {
0347: return new WrapMode(createMode(name,
0348: Constants.MODE_KIND_EDITOR,
0349: Constants.MODE_STATE_JOINED, false, null));
0350: } else {
0351: // #36945 In 'separate' ui mode create new mode.
0352: return createMode(name, Constants.MODE_KIND_VIEW,
0353: Constants.MODE_STATE_SEPARATED, false,
0354: new SplitConstraint[] { new SplitConstraint(
0355: Constants.HORIZONTAL, 1, 0.2) });
0356: }
0357: }
0358:
0359: private static class WrapMode implements Mode {
0360: private Mode wrap;
0361:
0362: public WrapMode(Mode wrap) {
0363: this .wrap = wrap;
0364: }
0365:
0366: public void addPropertyChangeListener(
0367: PropertyChangeListener list) {
0368: wrap.addPropertyChangeListener(list);
0369: }
0370:
0371: public boolean canDock(TopComponent tc) {
0372: return wrap.canDock(tc);
0373: }
0374:
0375: public boolean dockInto(TopComponent c) {
0376: if (c
0377: .getClientProperty(Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE) == null) {
0378: c.putClientProperty(
0379: Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE,
0380: Boolean.TRUE);
0381: }
0382: return wrap.dockInto(c);
0383: }
0384:
0385: public Rectangle getBounds() {
0386: return wrap.getBounds();
0387: }
0388:
0389: public String getDisplayName() {
0390: return wrap.getDisplayName();
0391: }
0392:
0393: public Image getIcon() {
0394: return wrap.getIcon();
0395: }
0396:
0397: public String getName() {
0398: return wrap.getName();
0399: }
0400:
0401: public TopComponent getSelectedTopComponent() {
0402: return wrap.getSelectedTopComponent();
0403: }
0404:
0405: public TopComponent[] getTopComponents() {
0406: return wrap.getTopComponents();
0407: }
0408:
0409: public Workspace getWorkspace() {
0410: return wrap.getWorkspace();
0411: }
0412:
0413: public void removePropertyChangeListener(
0414: PropertyChangeListener list) {
0415: wrap.removePropertyChangeListener(list);
0416: }
0417:
0418: public void setBounds(Rectangle s) {
0419: wrap.setBounds(s);
0420: }
0421: } // end of WrapMode
0422:
0423: /** Finds mode by specified name.
0424: * Implements <code>Workspace</code> interface method.
0425: * @param name the name of the mode to search for
0426: * @return the mode with that name, or <code>null</code> */
0427: public Mode findMode(String name) {
0428: return findModeImpl(name);
0429: }
0430:
0431: /** Finds mode the component is in.
0432: * Implements <code>Workspace</code> interface method.
0433: * @param c component to find mode for
0434: * @return the mode or <code>null</code> if the component is not in any mode */
0435: public Mode findMode(TopComponent tc) {
0436: if (tc == null) {
0437: // Log something?
0438: return null;
0439: }
0440:
0441: for (Iterator it = getModes().iterator(); it.hasNext();) {
0442: ModeImpl mode = (ModeImpl) it.next();
0443:
0444: if (mode.containsTopComponent(tc)) {
0445: return mode;
0446: }
0447: }
0448:
0449: return null;
0450: }
0451:
0452: /** Clears this workspace and removes this workspace from window manager.
0453: * Implements <code>Workspace</code> interface method.
0454: * @deprecated Doesn't have a sense now. Workspaces aren't supported anymore. */
0455: public void remove() {
0456: }
0457:
0458: ////////////////////////////////////
0459: // End of Workspace implementation<<
0460: ////////////////////////////////////
0461:
0462: //////////////////////////////
0463: // TopComponentGroup>>
0464: public void addTopComponentGroup(TopComponentGroupImpl tcGroup) {
0465: central.addTopComponentGroup(tcGroup);
0466: }
0467:
0468: public void removeTopComponentGroup(TopComponentGroupImpl tcGroup) {
0469: central.removeTopComponentGroup(tcGroup);
0470: }
0471:
0472: public Set<TopComponentGroupImpl> getTopComponentGroups() {
0473: return central.getTopComponentGroups();
0474: }
0475:
0476: // TopComponentGroup<<
0477: //////////////////////////////
0478:
0479: /// Copy from older WorkspaceImpl>>
0480:
0481: ////////////////////////////////////////////////////////
0482: // PENDING some of the next methods could make inner API
0483: /** Creates new mode.
0484: * @param name a unique programmatic name of the mode
0485: * @param permanent true if mode has to remain in model even it is emptied */
0486: public ModeImpl createMode(String name, int kind, int state,
0487: boolean permanent, SplitConstraint[] constraints) {
0488: // It gets existing mode with the same name.
0489: ModeImpl mode = (ModeImpl) findMode(name);
0490: if (mode != null) {
0491: return mode;
0492: }
0493:
0494: // XXX PENDING When no constraints are specified, default (editor or view) mode is returned.
0495: if (constraints == null && kind != Constants.MODE_KIND_SLIDING) {
0496: if (kind == Constants.MODE_KIND_EDITOR) {
0497: return getDefaultEditorMode();
0498: } else {
0499: return getDefaultViewMode();
0500: }
0501: }
0502:
0503: mode = createModeImpl(name, kind, state, permanent);
0504: addMode(mode, constraints);
0505: return mode;
0506: }
0507:
0508: public ModeImpl createSlidingMode(String name, boolean permanent,
0509: String side, Map<String, Integer> slideInSizes) {
0510: // It gets existing mode with the same name.
0511: ModeImpl mode = (ModeImpl) findMode(name);
0512: if (mode != null) {
0513: return mode;
0514: }
0515:
0516: mode = createModeImpl(name, Constants.MODE_KIND_SLIDING,
0517: permanent);
0518: central.addSlidingMode(mode, null, side, slideInSizes);
0519: return mode;
0520: }
0521:
0522: /*private*/ModeImpl createModeImpl(String name, int kind,
0523: boolean permanent) {
0524: int state = getEditorAreaState() == Constants.EDITOR_AREA_JOINED ? Constants.MODE_STATE_JOINED
0525: : Constants.MODE_STATE_SEPARATED;
0526: return createModeImpl(name, kind, state, permanent);
0527: }
0528:
0529: /** */
0530: /*private*/ModeImpl createModeImpl(String name, int kind,
0531: int state, boolean permanent) {
0532: if (name == null) {
0533: name = ModeImpl.getUnusedModeName();
0534: }
0535: ModeImpl toReturn = ModeImpl.createModeImpl(name, state, kind,
0536: permanent);
0537: return toReturn;
0538: }
0539:
0540: // XXX
0541: /** Gets default mode. */
0542: /*private*/ModeImpl getDefaultEditorMode() {
0543: ModeImpl mode = findModeImpl("editor"); // NOI18N
0544: if (mode == null) {
0545: Logger
0546: .getLogger(WindowManagerImpl.class.getName())
0547: .log(
0548: Level.INFO,
0549: null,
0550: new java.lang.IllegalStateException(
0551: "Creating default editor mode. It shouldn\'t happen this way")); // NOI18N
0552: // PENDING should be defined in winsys layer?
0553: ModeImpl newMode = createModeImpl("editor",
0554: Constants.MODE_KIND_EDITOR, true); // NOI18N
0555: addMode(newMode, new SplitConstraint[0]);
0556: return newMode;
0557: } else {
0558: return mode;
0559: }
0560: }
0561:
0562: // XXX
0563: /** Gets default view mode. */
0564: ModeImpl getDefaultViewMode() {
0565: ModeImpl mode = findModeImpl("explorer"); // NOI18N
0566: if (mode == null) {
0567: Logger
0568: .getLogger(WindowManagerImpl.class.getName())
0569: .log(
0570: Level.INFO,
0571: null,
0572: new java.lang.IllegalStateException(
0573: "Creating default view mode. It shouldn\'t happen this way")); // NOI18N
0574: // PENDING should be defined in winsys layer?
0575: ModeImpl newMode = createModeImpl("explorer",
0576: Constants.MODE_KIND_VIEW, true); // NOI18N
0577: addMode(newMode,
0578: new SplitConstraint[] {
0579: new SplitConstraint(Constants.VERTICAL, 0,
0580: 0.7D),
0581: new SplitConstraint(Constants.HORIZONTAL,
0582: 0, 0.25D) });
0583: return newMode;
0584: } else {
0585: return mode;
0586: }
0587: }
0588:
0589: /** Gets default sliding view mode. */
0590: ModeImpl getDefaultSlidingMode() {
0591: ModeImpl mode = findModeImpl("sliding"); // NOI18N
0592: if (mode == null) {
0593: Logger
0594: .getLogger(WindowManagerImpl.class.getName())
0595: .log(
0596: Level.INFO,
0597: null,
0598: new java.lang.IllegalStateException(
0599: "Creating default sliding mode. It shouldn\'t happen this way")); // NOI18N
0600: // PENDING should be defined in winsys layer?
0601: ModeImpl newMode = createModeImpl("sliding",
0602: Constants.MODE_KIND_SLIDING, true); // NOI18N
0603: addMode(newMode,
0604: new SplitConstraint[] {
0605: new SplitConstraint(Constants.VERTICAL, 0,
0606: 0.7D),
0607: new SplitConstraint(Constants.HORIZONTAL,
0608: 0, 0.25D) });
0609: return newMode;
0610: } else {
0611: return mode;
0612: }
0613: }
0614:
0615: private ModeImpl findModeImpl(String name) {
0616: if (name == null) {
0617: // PENDING log something?
0618: return null;
0619: }
0620:
0621: for (Iterator it = getModes().iterator(); it.hasNext();) {
0622: ModeImpl mode = (ModeImpl) it.next();
0623: if (name.equals(mode.getName())) {
0624: return mode;
0625: }
0626: }
0627:
0628: return null;
0629: }
0630:
0631: // XXX PENDING see WindowManager
0632: public TopComponent getSelectedTopComponent(Mode mode) {
0633: return central.getModeSelectedTopComponent((ModeImpl) mode);
0634: }
0635:
0636: public Rectangle getMainWindowBoundsJoined() {
0637: return central.getMainWindowBoundsJoined();
0638: }
0639:
0640: public void setMainWindowBoundsJoined(Rectangle bounds) {
0641: central.setMainWindowBoundsJoined(bounds);
0642: }
0643:
0644: public Rectangle getMainWindowBoundsSeparated() {
0645: return central.getMainWindowBoundsSeparated();
0646: }
0647:
0648: public void setMainWindowBoundsSeparated(Rectangle bounds) {
0649: central.setMainWindowBoundsSeparated(bounds);
0650: }
0651:
0652: public int getMainWindowFrameStateJoined() {
0653: return central.getMainWindowFrameStateJoined();
0654: }
0655:
0656: public void setMainWindowFrameStateJoined(int frameState) {
0657: central.setMainWindowFrameStateJoined(frameState);
0658: }
0659:
0660: public int getMainWindowFrameStateSeparated() {
0661: return central.getMainWindowFrameStateSeparated();
0662: }
0663:
0664: public void setMainWindowFrameStateSeparated(int frameState) {
0665: central.setMainWindowFrameStateSeparated(frameState);
0666: }
0667:
0668: /** Gets active mode.
0669: * @return active mode */
0670: public ModeImpl getActiveMode() {
0671: return central.getActiveMode();
0672: }
0673:
0674: /** Sets active mode.
0675: * @param current active mode */
0676: public void setActiveMode(ModeImpl activeMode) {
0677: central.setActiveMode(activeMode);
0678: }
0679:
0680: public void setEditorAreaBounds(Rectangle editorAreaBounds) {
0681: central.setEditorAreaBounds(editorAreaBounds);
0682: }
0683:
0684: public Rectangle getEditorAreaBounds() {
0685: return central.getEditorAreaBounds();
0686: }
0687:
0688: /** Sets editor area constraints. */
0689: public void setEditorAreaConstraints(
0690: SplitConstraint[] editorAreaConstraints) {
0691: central.setEditorAreaConstraints(editorAreaConstraints);
0692: }
0693:
0694: public java.awt.Component getEditorAreaComponent() {
0695: return central.getEditorAreaComponent();
0696: }
0697:
0698: /** Gets editor area constraints. */
0699: public SplitConstraint[] getEditorAreaConstraints() {
0700: return central.getEditorAreaConstraints();
0701: }
0702:
0703: /** Sets editor area state. */
0704: public void setEditorAreaState(int editorAreaState) {
0705: setEditorAreaStateImpl(editorAreaState);
0706: }
0707:
0708: // XXX
0709: void setEditorAreaStateImpl(int editorAreaState) {
0710: central.setEditorAreaState(editorAreaState);
0711: }
0712:
0713: public int getEditorAreaState() {
0714: return central.getEditorAreaState();
0715: }
0716:
0717: public void setEditorAreaFrameState(int editorAreaFrameState) {
0718: central.setEditorAreaFrameState(editorAreaFrameState);
0719: }
0720:
0721: public int getEditorAreaFrameState() {
0722: return central.getEditorAreaFrameState();
0723: }
0724:
0725: /**
0726: * Sets new maximized mode or cancels the current one.
0727: * @param newMaximizedMode Mode to set as the maximized one or null to cancel the current one.
0728: */
0729: public void switchMaximizedMode(ModeImpl newMaximizedMode) {
0730: central.switchMaximizedMode(newMaximizedMode);
0731: }
0732:
0733: /** Sets editor mode that is currenlty maximized (used when the window system loads) */
0734: public void setEditorMaximizedMode(ModeImpl editorMaximizedMode) {
0735: central.setEditorMaximizedMode(editorMaximizedMode);
0736: }
0737:
0738: /** Sets view mode that is currenlty maximized (used when the window system loads) */
0739: public void setViewMaximizedMode(ModeImpl viewMaximizedMode) {
0740: central.setViewMaximizedMode(viewMaximizedMode);
0741: }
0742:
0743: /** Gets mode that is currently maximized. */
0744: public ModeImpl getCurrentMaximizedMode() {
0745: return central.getCurrentMaximizedMode();
0746: }
0747:
0748: /** Gets editor maximized mode. */
0749: public ModeImpl getEditorMaximizedMode() {
0750: return central.getEditorMaximizedMode();
0751: }
0752:
0753: /** Gets view maximized mode. */
0754: public ModeImpl getViewMaximizedMode() {
0755: return central.getViewMaximizedMode();
0756: }
0757:
0758: /** Sets constraints, delegates from ModeImpl. */
0759: public void setModeConstraints(ModeImpl mode,
0760: SplitConstraint[] modeConstraints) {
0761: central.setModeConstraints(mode, modeConstraints);
0762: }
0763:
0764: /** Gets constraints, delegates from ModeImpl. */
0765: public SplitConstraint[] getModeConstraints(ModeImpl mode) {
0766: return central.getModeConstraints(mode);
0767: }
0768:
0769: /** Adds mode. */
0770: private void addMode(ModeImpl mode,
0771: SplitConstraint[] modeConstraints) {
0772: if (mode.getKind() == Constants.MODE_KIND_SLIDING) {
0773: // TODO.. where to get the side..
0774: central.addSlidingMode(mode, null, Constants.LEFT, null);
0775: } else {
0776: central.addMode(mode, modeConstraints);
0777: }
0778: }
0779:
0780: /** Removes mode. */
0781: public void removeMode(ModeImpl mode) {
0782: if (mode.getKind() == Constants.MODE_KIND_SLIDING) {
0783:
0784: } else {
0785: central.removeMode(mode);
0786: }
0787: }
0788:
0789: /** Sets toolbar configuration name. */
0790: public void setToolbarConfigName(String toolbarConfigName) {
0791: central.setToolbarConfigName(toolbarConfigName);
0792: }
0793:
0794: /** Gets toolbar configuration name.
0795: * @return toolbar configuration name */
0796: public String getToolbarConfigName() {
0797: return central.getToolbarConfigName();
0798: }
0799:
0800: // Copy from older WorkspaceImpl<<
0801:
0802: /** Sets visible or invisible window system GUI. */
0803: public void setVisible(boolean visible) {
0804: if (visible) {
0805: FloatingWindowTransparencyManager.getDefault().start();
0806: } else {
0807: FloatingWindowTransparencyManager.getDefault().stop();
0808: }
0809: SwingUtilities.invokeLater(exclusive);
0810: central.setVisible(visible);
0811: }
0812:
0813: /** Indicates whether windows system shows GUI. */
0814: public boolean isVisible() {
0815: return central.isVisible();
0816: }
0817:
0818: /** Attaches TopComponent to one side of mode, it removes it from original one. */
0819: public void attachTopComponentToSide(TopComponent tc,
0820: ModeImpl attachMode, String side) {
0821: central.attachTopComponentsToSide(new TopComponent[] { tc },
0822: attachMode, side);
0823: }
0824:
0825: // XXX
0826: public TopComponent getTopComponentForID(String tcID) {
0827: return PersistenceHandler.getDefault().getTopComponentForID(
0828: tcID, true);
0829: }
0830:
0831: public boolean isTopComponentAllowedToMoveAnywhere(TopComponent tc) {
0832: if (Boolean.TRUE
0833: .equals(tc
0834: .getClientProperty(Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE))) {
0835: return true;
0836: }
0837:
0838: return false;
0839: }
0840:
0841: // XXX
0842: public ModeImpl findModeForOpenedID(String tcID) {
0843: if (tcID == null) {
0844: return null;
0845: }
0846:
0847: for (ModeImpl mode : getModes()) {
0848: if (mode.getOpenedTopComponentsIDs().contains(tcID)) {
0849: return mode;
0850: }
0851: }
0852:
0853: return null;
0854: }
0855:
0856: // XXX
0857: public ModeImpl findModeForClosedID(String tcID) {
0858: if (tcID == null) {
0859: return null;
0860: }
0861:
0862: for (ModeImpl mode : getModes()) {
0863: if (mode.getClosedTopComponentsIDs().contains(tcID)) {
0864: return mode;
0865: }
0866: }
0867:
0868: return null;
0869: }
0870:
0871: private static final boolean NAME_HACK = Boolean
0872: .getBoolean("nb.tabnames.html"); //NOI18N
0873:
0874: /** Helper method to retrieve some form of display name of TopComponent.
0875: * First tries TopComponent's getHtmlDisplayName, if is it null then continues
0876: * with getDisplayName and getName in this order.
0877: *
0878: * @param tc TopComponent to retrieve display name from. May be null.
0879: * @return TopComponent's display name or null if no display name available
0880: * or null TopComponent is given
0881: */
0882: public String getTopComponentDisplayName(TopComponent tc) {
0883: if (tc == null) {
0884: return null;
0885: }
0886: String displayName = tc.getHtmlDisplayName();
0887: if (displayName == null) {
0888: displayName = tc.getDisplayName();
0889: }
0890: if (displayName == null) {
0891: displayName = tc.getName();
0892: }
0893: if (NAME_HACK && displayName != null) {
0894: //THIS IS FOR DEMO PURPOSES ONLY! A PROPER API IS NEEDED
0895: //(TopComponent.getHtmlDisplayName()), OR
0896: //HTML SHOULD BE PRE-SUPPLIED
0897: if (displayName.endsWith("*")) {
0898:
0899: if (displayName.startsWith("<html>")) {
0900: displayName = displayName.substring(6);
0901: }
0902:
0903: displayName = "<html><b>"
0904: + displayName.substring(0,
0905: displayName.length() - 2);
0906:
0907: } else {
0908:
0909: int i = displayName.indexOf("[r/o]");
0910: if (i > 0) {
0911:
0912: if (displayName.startsWith("<html>")) {
0913: displayName = displayName.substring(6);
0914: i -= 6;
0915: }
0916:
0917: int roLength = "[r/o]".length();
0918: String nuName = "<html><font color='#555555'><i>" + //NOI18N
0919: displayName.substring(0, i - 1);
0920: if (i + roLength < displayName.length()) {
0921: nuName += displayName.substring(i + roLength);
0922: }
0923: displayName = nuName;
0924: }
0925: }
0926: }
0927: return displayName;
0928: }
0929:
0930: // PENDING for ModeImpl only.
0931: Central getCentral() {
0932: return central;
0933: }
0934:
0935: // XXX
0936: public boolean isDragInProgress() {
0937: return central.isDragInProgress();
0938: }
0939:
0940: /** Analyzes bounds of given top component and finds appropriate side
0941: * of desktop for sliding for given top component.
0942: *
0943: * @param tc top component to find side for sliding for
0944: * @return side where top component should live in sliding state
0945: * @see Constants.LEFT
0946: */
0947: public String guessSlideSide(TopComponent tc) {
0948: return central.guessSlideSide(tc);
0949: }
0950:
0951: /**
0952: * {@inheritDoc}
0953: */
0954: public boolean isDocked(TopComponent comp) {
0955: return central.isDocked(comp);
0956: }
0957:
0958: /** Takes given top component out of the main window and puts it in
0959: * new separate floating window.
0960: *
0961: * @param tc TopComponent to make floating
0962: * @param mode mode where TopComponent currently lives (before undock)
0963: *
0964: * @throws IllegalStateException when given top component is already floating
0965: */
0966: public void userUndockedTopComponent(TopComponent tc, ModeImpl mode) {
0967: if (!isDocked(tc)) {
0968: throw new IllegalStateException(
0969: "TopComponent is already in floating state: " + tc);
0970: }
0971:
0972: central.userUndockedTopComponent(tc, mode);
0973: }
0974:
0975: /** Puts given top component back into main window.
0976: *
0977: * @param tc TopComponent to put back into main window
0978: * @param mode mode where TopComponent currently lives (before dock)
0979: *
0980: * @throws IllegalStateException when given top component is already inside main window
0981: */
0982: public void userDockedTopComponent(TopComponent tc, ModeImpl mode) {
0983: if (isDocked(tc)) {
0984: throw new IllegalStateException(
0985: "TopComponent is already inside main window: " + tc);
0986: }
0987:
0988: central.userDockedTopComponent(tc, mode);
0989: }
0990:
0991: // PENDING>>
0992: public void setRecentViewList(TopComponent[] tcs) {
0993: recentViewList.setTopComponents(tcs);
0994: }
0995:
0996: public TopComponent[] getRecentViewList() {
0997: return recentViewList.getTopComponents();
0998: }
0999:
1000: // PENDING<<
1001:
1002: void doFirePropertyChange(final String propName,
1003: final Object oldValue, final Object newValue) {
1004: // PENDING When #37529 finished, then uncomment the next row and move the
1005: // checks of AWT thread away.
1006: // WindowManagerImpl.assertEventDispatchThread();
1007: if (SwingUtilities.isEventDispatchThread()) {
1008: changeSupport.firePropertyChange(propName, oldValue,
1009: newValue);
1010: } else {
1011: SwingUtilities.invokeLater(new Runnable() {
1012: public void run() {
1013: changeSupport.firePropertyChange(propName,
1014: oldValue, newValue);
1015: }
1016: });
1017: }
1018: }
1019:
1020: // PENDING used in persistence only, revise how to restrict its usage only there.
1021: /** Gets persistence observer. */
1022: public org.netbeans.core.windows.persistence.PersistenceObserver getPersistenceObserver() {
1023: return PersistenceHandler.getDefault();
1024: }
1025:
1026: /////////////////////////
1027: // Notifications>>
1028: public void notifyTopComponentOpened(TopComponent tc) {
1029: // Inform component instance.
1030: componentOpenNotify(tc);
1031: // then let others know that top component was opened...
1032: notifyRegistryTopComponentOpened(tc);
1033: }
1034:
1035: public void notifyTopComponentClosed(TopComponent tc) {
1036: // Inform component instance.
1037: componentCloseNotify(tc);
1038: // let others know that top component was closed...
1039: notifyRegistryTopComponentClosed(tc);
1040: }
1041:
1042: // Notifications<<
1043: /////////////////////////
1044:
1045: /////////////////////////////
1046: // Registry notifications
1047: static void notifyRegistryTopComponentActivated(
1048: final TopComponent tc) {
1049: ((RegistryImpl) getDefault().getRegistry())
1050: .topComponentActivated(tc);
1051:
1052: // #37457 It is needed to ensure the activation calls are in AWT thread.
1053: if (SwingUtilities.isEventDispatchThread()) {
1054: WindowManagerImpl.getInstance().activateComponent(tc);
1055: } else {
1056: SwingUtilities.invokeLater(new Runnable() {
1057: public void run() {
1058: WindowManagerImpl.getInstance().activateComponent(
1059: tc);
1060: }
1061: });
1062: }
1063: }
1064:
1065: private static void notifyRegistryTopComponentOpened(TopComponent tc) {
1066: ((RegistryImpl) getDefault().getRegistry())
1067: .topComponentOpened(tc);
1068: }
1069:
1070: private static void notifyRegistryTopComponentClosed(TopComponent tc) {
1071: ((RegistryImpl) getDefault().getRegistry())
1072: .topComponentClosed(tc);
1073: }
1074:
1075: private static void notifyRegistrySelectedNodesChanged(
1076: TopComponent tc, Node[] nodes) {
1077: ((RegistryImpl) getDefault().getRegistry())
1078: .selectedNodesChanged(tc, nodes);
1079: }
1080:
1081: // Registry notifications
1082: /////////////////////////////
1083:
1084: /** Overrides superclass method, to enhance access modifier. */
1085: @Override
1086: public void componentShowing(TopComponent tc) {
1087: if ((tc != null) && (tc != persistenceShowingTC)) {
1088: super .componentShowing(tc);
1089: }
1090: }
1091:
1092: /** XXX - Hack for 40237, should be changed to fix real reason of 37188
1093: * timing of activate events */
1094: void specialPersistenceCompShow(TopComponent tc) {
1095: componentShowing(tc);
1096: persistenceShowingTC = tc;
1097: }
1098:
1099: /** Overrides superclass method, to enhance access modifier. */
1100: @Override
1101: public void componentHidden(TopComponent tc) {
1102: if (tc != null) {
1103: super .componentHidden(tc);
1104: if (tc == persistenceShowingTC) {
1105: persistenceShowingTC = null;
1106: }
1107: }
1108: }
1109:
1110: // Manipulating methods (overriding the superclass dummy ones) >>
1111: protected void topComponentOpen(TopComponent tc) {
1112: topComponentOpenAtTabPosition(tc, -1);
1113: }
1114:
1115: @Override
1116: protected void topComponentOpenAtTabPosition(TopComponent tc,
1117: int position) {
1118: assertEventDispatchThreadWeak();
1119:
1120: if (tc == null) {
1121: throw new IllegalArgumentException("Cannot open a null "
1122: + "TopComponent"); //NOI18N
1123: }
1124:
1125: ModeImpl mode = getMode(tc);
1126:
1127: if (mode == null) {
1128: mode = getDefaultEditorMode();
1129: if (tc
1130: .getClientProperty(Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE) == null) {
1131: tc.putClientProperty(
1132: Constants.TOPCOMPONENT_ALLOW_DOCK_ANYWHERE,
1133: Boolean.TRUE);
1134: }
1135: }
1136: boolean alreadyOpened = mode.getOpenedTopComponents().contains(
1137: tc);
1138:
1139: // XXX PENDING If necessary, unmaximize the state, but exclude sliding modes
1140: // Consider to put it in addOpenedTopComponent, to do it in one step.
1141: ModeImpl maximizedMode = getCurrentMaximizedMode();
1142: if (maximizedMode != null && mode != maximizedMode
1143: && mode.getKind() != Constants.MODE_KIND_SLIDING
1144: && central.isViewMaximized()) {
1145: switchMaximizedMode(null);
1146: }
1147:
1148: if (position == -1) {
1149: mode.addOpenedTopComponent(tc);
1150: } else {
1151: mode.addOpenedTopComponent(tc, position);
1152: }
1153:
1154: if (central.isEditorMaximized() && !alreadyOpened
1155: && mode.getState() != Constants.MODE_STATE_SEPARATED) {
1156: //the editor is maximized so the newly opened TopComponent should slide out
1157: String tcID = findTopComponentID(tc);
1158: if (!isTopComponentDockedInMaximizedMode(tcID)
1159: && mode.getKind() == Constants.MODE_KIND_VIEW) {
1160: //slide the TopComponent to edgebar and slide it out
1161: central.slide(tc, mode, central
1162: .getSlideSideForMode(mode));
1163:
1164: topComponentRequestActive(tc);
1165: }
1166: }
1167: }
1168:
1169: @Override
1170: protected int topComponentGetTabPosition(TopComponent tc) {
1171: assertEventDispatchThreadWeak();
1172:
1173: ModeImpl mode = getModeForOpenedTopComponent(tc);
1174: if (mode != null) {
1175: return mode.getTopComponentTabPosition(tc);
1176: } else {
1177: return -1;
1178: }
1179: }
1180:
1181: protected void topComponentClose(TopComponent tc) {
1182: assertEventDispatchThreadWeak();
1183:
1184: boolean opened = topComponentIsOpened(tc);
1185: if (!opened) {
1186: return;
1187: }
1188:
1189: ModeImpl mode = getModeForOpenedTopComponent(tc);
1190: if (mode != null) {
1191: if (mode == central.getCurrentMaximizedMode()
1192: && central.isViewMaximized()) {
1193: central.switchMaximizedMode(null);
1194: topComponentClose(tc);
1195: } else {
1196: TopComponent recentTc = null;
1197: if (mode.getKind() == Constants.MODE_KIND_EDITOR) {
1198: //an editor document is being closed so let's find the most recent editor to select
1199: recentTc = central.getRecentTopComponent(mode, tc);
1200: }
1201: mode.close(tc);
1202: if (null != recentTc)
1203: recentTc.requestActive();
1204: }
1205: }
1206: }
1207:
1208: protected void topComponentRequestActive(TopComponent tc) {
1209: assertEventDispatchThreadWeak();
1210:
1211: ModeImpl mode = getModeForOpenedTopComponent(tc);
1212: if (mode != null) {
1213: central.activateModeTopComponent(mode, tc);
1214: }
1215: }
1216:
1217: protected void topComponentRequestVisible(TopComponent tc) {
1218: assertEventDispatchThreadWeak();
1219:
1220: ModeImpl mode = getModeForOpenedTopComponent(tc);
1221: if (mode != null) {
1222: central.setModeSelectedTopComponent(mode, tc);
1223: }
1224: }
1225:
1226: protected void topComponentDisplayNameChanged(TopComponent tc,
1227: String displayName) {
1228: assertEventDispatchThreadWeak();
1229:
1230: ModeImpl mode = getModeForOpenedTopComponent(tc);
1231: if (mode != null) {
1232: central.topComponentDisplayNameChanged(mode, tc);
1233: }
1234: }
1235:
1236: protected void topComponentHtmlDisplayNameChanged(TopComponent tc,
1237: String htmlDisplayName) {
1238: // do the same thing as for display name, we can because string param is ignored
1239: topComponentDisplayNameChanged(tc, null);
1240: }
1241:
1242: protected void topComponentToolTipChanged(TopComponent tc,
1243: String toolTip) {
1244: assertEventDispatchThreadWeak();
1245:
1246: ModeImpl mode = getModeForOpenedTopComponent(tc);
1247: if (mode != null) {
1248: central.topComponentToolTipChanged(mode, tc);
1249: }
1250: }
1251:
1252: protected void topComponentIconChanged(TopComponent tc, Image icon) {
1253: assertEventDispatchThreadWeak();
1254:
1255: ModeImpl mode = getModeForOpenedTopComponent(tc);
1256: if (mode != null) {
1257: central.topComponentIconChanged(mode, tc);
1258: }
1259: }
1260:
1261: protected void topComponentActivatedNodesChanged(TopComponent tc,
1262: Node[] activatedNodes) {
1263: assertEventDispatchThreadWeak();
1264:
1265: notifyRegistrySelectedNodesChanged(tc, activatedNodes);
1266: }
1267:
1268: protected boolean topComponentIsOpened(TopComponent tc) {
1269: assertEventDispatchThreadWeak();
1270:
1271: return getModeForOpenedTopComponent(tc) != null;
1272: }
1273:
1274: protected Action[] topComponentDefaultActions(TopComponent tc) {
1275: assertEventDispatchThreadWeak();
1276:
1277: return ActionUtils.createDefaultPopupActions(tc);
1278: }
1279:
1280: protected String topComponentID(TopComponent tc, String preferredID) {
1281: assertEventDispatchThreadWeak();
1282:
1283: if (preferredID == null) {
1284: Logger
1285: .getLogger(WindowManagerImpl.class.getName())
1286: .log(
1287: Level.WARNING,
1288: null,
1289: new java.lang.IllegalStateException(
1290: "Assertion failed. "
1291: + tc.getClass().getName()
1292: + ".preferredID method shouldn\'t be overriden to return null. "
1293: + "Please change your impl to return non-null string.")); // NOI18N
1294: }
1295:
1296: return PersistenceManager.getDefault().getGlobalTopComponentID(
1297: tc, preferredID);
1298: }
1299:
1300: @Override
1301: public void invokeWhenUIReady(Runnable run) {
1302: exclusive.register(run);
1303: }
1304:
1305: @Override
1306: public boolean isEditorTopComponent(TopComponent tc) {
1307: if (null == tc)
1308: return false;
1309: //check opened TopComponents first to avoid AWT assertion if possible
1310: for (ModeImpl mode : getModes()) {
1311: if (mode.containsTopComponent(tc)) {
1312: return mode.getKind() == Constants.MODE_KIND_EDITOR;
1313: }
1314: }
1315:
1316: //unknown TopComponent
1317: return false;
1318: }
1319:
1320: @Override
1321: public boolean isOpenedEditorTopComponent(TopComponent tc) {
1322: if (null == tc)
1323: return false;
1324: for (ModeImpl mode : getModes()) {
1325: if (mode.getOpenedTopComponents().contains(tc)) {
1326: return mode.getKind() == Constants.MODE_KIND_EDITOR;
1327: }
1328: }
1329:
1330: //unknown TopComponent
1331: return false;
1332: }
1333:
1334: @Override
1335: public boolean isEditorMode(Mode mode) {
1336: if (null == mode)
1337: return false;
1338: ModeImpl modeImpl = findModeImpl(mode.getName());
1339: return null != modeImpl
1340: && modeImpl.getKind() == Constants.MODE_KIND_EDITOR;
1341: }
1342:
1343: /** Handles exclusive invocation of Runnables.
1344: */
1345: private static final class Exclusive implements Runnable {
1346: /** lists of runnables to run */
1347: private ArrayList<Runnable> arr = new ArrayList<Runnable>();
1348:
1349: /** Registers given runnable and ensures that it is run when UI
1350: * of the system is ready.
1351: */
1352: public synchronized void register(Runnable r) {
1353: arr.add(r);
1354: SwingUtilities.invokeLater(this );
1355: }
1356:
1357: public void run() {
1358: if (!WindowManagerImpl.getInstance().isVisible()) {
1359: return;
1360: }
1361:
1362: ArrayList<Runnable> arrCopy = null;
1363: synchronized (this ) {
1364: if (arr.isEmpty()) {
1365: return;
1366: }
1367:
1368: arrCopy = arr;
1369: arr = new ArrayList<Runnable>();
1370: }
1371:
1372: for (Runnable r : arrCopy) {
1373: try {
1374: r.run();
1375: } catch (RuntimeException ex) {
1376: Logger.getLogger(WindowManagerImpl.class.getName())
1377: .log(Level.WARNING, null, ex);
1378: }
1379: }
1380: }
1381: } // end of Exclusive class
1382:
1383: public void resetModel() {
1384: central.resetModel();
1385: RegistryImpl rimpl = (RegistryImpl) componentRegistry();
1386: rimpl.clear();
1387: }
1388:
1389: // Manipulating methods (overriding the superclass dummy ones) <<
1390:
1391: /** Helper only. */
1392: private ModeImpl getMode(TopComponent tc) {
1393: return (ModeImpl) findMode(tc);
1394: }
1395:
1396: // #37561
1397: /** Helper only */
1398: private ModeImpl getModeForOpenedTopComponent(TopComponent tc) {
1399: if (tc == null) {
1400: // Log something?
1401: return null;
1402: }
1403:
1404: for (ModeImpl mode : getModes()) {
1405: if (mode.getOpenedTopComponents().contains(tc)) {
1406: return mode;
1407: }
1408: }
1409:
1410: return null;
1411: }
1412:
1413: /**
1414: * @return The mode where the given TopComponent had been before it was moved to sliding or separate mode.
1415: */
1416: public ModeImpl getPreviousModeForTopComponent(String tcID,
1417: ModeImpl slidingMode) {
1418: return getCentral().getModeTopComponentPreviousMode(tcID,
1419: slidingMode);
1420: }
1421:
1422: /**
1423: * @return The position (tab index) of the given TopComponent before it was moved to sliding or separate mode.
1424: */
1425: public int getPreviousIndexForTopComponent(String tcID,
1426: ModeImpl slidingMode) {
1427: return getCentral().getModeTopComponentPreviousIndex(tcID,
1428: slidingMode);
1429:
1430: }
1431:
1432: /**
1433: * Remember the mode and position where the given TopComponent was before moving into sliding or separate mode.
1434: *
1435: * @param tcID TopComponent's id
1436: * @param currentSlidingMode The mode where the TopComponent is at the moment.
1437: * @param prevMode The mode where the TopComponent had been before it was moved to the sliding mode.
1438: * @param prevIndex Tab index of the TopComponent before it was moved to the new mode.
1439: */
1440: public void setPreviousModeForTopComponent(String tcID,
1441: ModeImpl slidingMode, ModeImpl prevMode, int prevIndex) {
1442: getCentral().setModeTopComponentPreviousMode(tcID, slidingMode,
1443: prevMode, prevIndex);
1444: }
1445:
1446: /**
1447: * Set the state of the TopComponent when the editor is maximized.
1448: *
1449: * @param tcID TopComponent id
1450: * @param docked True if the TopComponent should stay docked in maximized editor mode,
1451: * false if it should slide out when the editor is maximized.
1452: */
1453: public void setTopComponentDockedInMaximizedMode(String tcID,
1454: boolean docked) {
1455: getCentral().setTopComponentDockedInMaximizedMode(tcID, docked);
1456: }
1457:
1458: /**
1459: * Get the state of the TopComponent when the editor is maximized.
1460: *
1461: * @param tcID TopComponent id.
1462: * @return True if the TopComponent should stay docked in maximized editor mode,
1463: * false if it should slide out when the editor is maximized.
1464: */
1465: public boolean isTopComponentDockedInMaximizedMode(String tcID) {
1466: return getCentral().isTopComponentDockedInMaximizedMode(tcID);
1467: }
1468:
1469: /**
1470: * Set the state of the TopComponent when no mode is maximized.
1471: *
1472: * @param tcID TopComponent id
1473: * @param slided True if the TopComponent is slided in the default mode,
1474: * false if it is docked.
1475: */
1476: public void setTopComponentSlidedInDefaultMode(String tcID,
1477: boolean slided) {
1478: getCentral().setTopComponentSlidedInDefaultMode(tcID, slided);
1479: }
1480:
1481: /**
1482: * Get the state of the TopComponent when no mode is maximized.
1483: *
1484: * @param tcID TopComponent id.
1485: * @return True if the TopComponent is slided in the default mode,
1486: * false if it is docked.
1487: */
1488: public boolean isTopComponentSlidedInDefaultMode(String tcID) {
1489: return getCentral().isTopComponentSlidedInDefaultMode(tcID);
1490: }
1491:
1492: /**
1493: * Get the state of the TopComponent when it is slided-in.
1494: *
1495: * @param tcID TopComponent id.
1496: * @return true if the TopComponent is maximized when slided-in.
1497: */
1498: public boolean isTopComponentMaximizedWhenSlidedIn(String tcID) {
1499: return getCentral().isTopComponentMaximizedWhenSlidedIn(tcID);
1500: }
1501:
1502: /**
1503: * Set the state of the TopComponent when it is slided-in.
1504: *
1505: * @param tcID TopComponent id.
1506: * @param maximized true if the TopComponent is maximized when slided-in.
1507: */
1508: public void setTopComponentMaximizedWhenSlidedIn(String tcID,
1509: boolean maximized) {
1510: getCentral().setTopComponentMaximizedWhenSlidedIn(tcID,
1511: maximized);
1512: }
1513:
1514: public void userToggledTopComponentSlideInMaximize(String tcID) {
1515: getCentral().userToggledTopComponentSlideInMaximize(tcID);
1516: }
1517:
1518: /** Finds out if given Window is used as separate floating window or not.
1519: *
1520: * @return true if Window is separate floating window, false if window
1521: * is used for other purposes such as independent dialog/window, main window etc.
1522: */
1523: public static boolean isSeparateWindow(Window w) {
1524: // work only in Swing environment
1525: if (!(w instanceof RootPaneContainer)) {
1526: return false;
1527: }
1528: // #85089 - getRootPane may return null in some edge situations
1529: JRootPane rp = ((RootPaneContainer) w).getRootPane();
1530: if (rp == null) {
1531: return false;
1532: }
1533: return rp.getClientProperty(Constants.SEPARATE_WINDOW_PROPERTY) != null;
1534: }
1535:
1536: private static final String ASSERTION_ERROR_MESSAGE = "WindowsAPI is required to be called from AWT thread only, see " // NOI18N
1537: + "http://core.netbeans.org/proposals/threading/"; // NOI18N
1538:
1539: static void assertEventDispatchThread() {
1540: assert SwingUtilities.isEventDispatchThread() : ASSERTION_ERROR_MESSAGE;
1541: }
1542:
1543: // PENDING Just temporary until all 'bad' calls are really put into AWT thread.
1544: static void assertEventDispatchThreadWeak() {
1545: if (!SwingUtilities.isEventDispatchThread()) {
1546: Logger.getLogger(WindowManagerImpl.class.getName()).log(
1547: Level.WARNING,
1548: null,
1549: new java.lang.IllegalStateException(
1550: "Assertion failed. "
1551: + ASSERTION_ERROR_MESSAGE)); // NOI18N
1552: }
1553: }
1554:
1555: /**
1556: * @return An array of TopComponents that are opened in editor modes (i.e. editor windows).
1557: */
1558: public TopComponent[] getEditorTopComponents() {
1559: ArrayList<TopComponent> editors = new ArrayList<TopComponent>();
1560: Set<? extends Mode> modes = getModes();
1561: for (Mode mode : modes) {
1562: ModeImpl modeImpl = findModeImpl(mode.getName()); // XXX probably useless
1563: if (modeImpl.getKind() == Constants.MODE_KIND_EDITOR) {
1564: editors.addAll(modeImpl.getOpenedTopComponents());
1565: }
1566: }
1567: return editors.toArray(new TopComponent[editors.size()]);
1568: }
1569:
1570: /**
1571: * @return TopComponent that is selected in an arbitrary editor-type mode
1572: * or null if editor mode(s) is empty.
1573: */
1574: public TopComponent getArbitrarySelectedEditorTopComponent() {
1575: Set modes = getModes();
1576: for (Iterator i = modes.iterator(); i.hasNext();) {
1577: Mode mode = (Mode) i.next();
1578: ModeImpl modeImpl = findModeImpl(mode.getName());
1579: if (modeImpl.getKind() == Constants.MODE_KIND_EDITOR) {
1580: return mode.getSelectedTopComponent();
1581: }
1582: }
1583: return null;
1584: }
1585:
1586: /**
1587: * Send componentHidden() event to all selected TopComponents in editor modes.
1588: */
1589: public void deselectEditorTopComponents() {
1590: for (ModeImpl modeImpl : getModes()) {
1591: if (modeImpl.getKind() == Constants.MODE_KIND_EDITOR) {
1592: //not a pretty hack - add an empty TopComponent into the mode
1593: //and make it the selected one so that componentHidden() gets called
1594: //on the previously selected TopComponent
1595: TopComponent dummy = new DummyTopComponent();
1596: modeImpl.addOpenedTopComponent(dummy);
1597: modeImpl.setSelectedTopComponent(dummy);
1598: }
1599: }
1600: }
1601:
1602: /**
1603: * Calls close() on all TopComponents that are opened in noneditor-type modes.
1604: *
1605: */
1606: public void closeNonEditorViews() {
1607: for (ModeImpl modeImpl : getModes()) {
1608: if (null != modeImpl
1609: && modeImpl.getKind() != Constants.MODE_KIND_EDITOR) {
1610: java.util.List tcs = modeImpl.getOpenedTopComponents();
1611: for (Iterator j = tcs.iterator(); j.hasNext();) {
1612: TopComponent tc = (TopComponent) j.next();
1613: tc.close();
1614: }
1615: }
1616: }
1617: }
1618:
1619: /**
1620: * An empty TopComponent needed for deselectEditorTopComponents()
1621: */
1622: private static class DummyTopComponent extends TopComponent {
1623: protected String preferredID() {
1624: return "temp";
1625: }
1626:
1627: public int getPersistenceType() {
1628: return PERSISTENCE_NEVER;
1629: }
1630: }
1631: }
|