diff --git a/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java b/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java --- a/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java +++ b/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java @@ -65,6 +65,7 @@ import org.netbeans.core.windows.TopComponentGroupImpl; import org.netbeans.core.windows.WindowManagerImpl; import org.netbeans.core.windows.WindowSystemSnapshot; +import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; @@ -249,9 +250,9 @@ modesSubModel.addMode(mode, constraints); } } - - + + // XXX public void addModeToSide(ModeImpl mode, ModeImpl attachMode, String side) { synchronized(LOCK_MODES) { @@ -784,7 +785,17 @@ public boolean isModePermanent(ModeImpl mode) { ModeModel modeModel = getModelForMode(mode); if(modeModel != null) { - return modeModel.isPermanent(); + boolean result = modeModel.isPermanent(); + if (!result) { + for (TopComponent tc : mode.getTopComponents()) { + result |= tc.getClass().getAnnotation(RetainLocation.class) + != null; + if (result) { + break; + } + } + } + return result; } else { return false; } diff --git a/openide.windows/manifest.mf b/openide.windows/manifest.mf --- a/openide.windows/manifest.mf +++ b/openide.windows/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.windows -OpenIDE-Module-Specification-Version: 6.31 +OpenIDE-Module-Specification-Version: 6.32 OpenIDE-Module-Localizing-Bundle: org/openide/windows/Bundle.properties AutoUpdate-Essential-Module: true diff --git a/openide.windows/src/org/openide/windows/RetainLocation.java b/openide.windows/src/org/openide/windows/RetainLocation.java new file mode 100644 --- /dev/null +++ b/openide.windows/src/org/openide/windows/RetainLocation.java @@ -0,0 +1,63 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.openide.windows; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * Annotation which can be applied to TopComponents whose persistence type + * is PERSISTENCE_NEVER to allow them to remember the location they were + * docked into + * + * @since 6.32 + * @author Tim Boudreau + */ +@Retention (RUNTIME) +@Target (ElementType.TYPE) +public @interface RetainLocation { + /** The name of the docking location (Mode) this component should be + * docked into by default, if there is no stored value. + * @return The Mode name + */ + String value(); +} diff --git a/openide.windows/src/org/openide/windows/TopComponent.java b/openide.windows/src/org/openide/windows/TopComponent.java --- a/openide.windows/src/org/openide/windows/TopComponent.java +++ b/openide.windows/src/org/openide/windows/TopComponent.java @@ -91,10 +91,10 @@ import org.openide.util.HelpCtx; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.NbPreferences; import org.openide.util.Utilities; import org.openide.util.WeakListeners; import org.openide.util.WeakSet; -import org.openide.util.actions.NodeAction; import org.openide.util.actions.SystemAction; /** @@ -243,6 +243,8 @@ */ public static final String PROP_MAXIMIZATION_DISABLED = "netbeans.winsys.tc.maximization_disabled"; //NOI18N + private transient String modeName; + /** Create a top component. */ public TopComponent() { @@ -270,6 +272,45 @@ initActionMap(lookup); } + private static final String MODE_ID_PREFERENCES_KEY_INFIX = "_modeId_"; //NOI18N + @Override + public void addNotify() { + super.addNotify(); + if (isPersistLocation()) { + Mode m = WindowManager.getDefault().findMode(this); + if (m != null) { + modeName = m.getName(); + if (modeName == null) { + modeName = getClass().getAnnotation( + RetainLocation.class).value(); + } + NbPreferences.forModule(getClass()).put(getModeIdKey(), modeName); + } + } + } + + private boolean isPersistLocation() { + boolean result = getPersistenceType() == PERSISTENCE_NEVER && + getClass().getAnnotation(RetainLocation.class) != null; + assert annotationAndPersistenceTypeAreCompatible(); + return result; + } + + private boolean annotationAndPersistenceTypeAreCompatible() { + if (getPersistenceType() != PERSISTENCE_NEVER && + getClass().getAnnotation(RetainLocation.class) != null) { + Logger.getLogger(TopComponent.class.getName()).log(Level.WARNING, + "Useless to annotate a TopComponent with @RetainLocation if " + //NOI18N + "its persistence type is not PERSISTENCE_NEVER: {0}", //NOI18N + new Object[] { getClass().getName() }); + } + return true; + } + + private String getModeIdKey() { + return getClass().getName() + MODE_ID_PREFERENCES_KEY_INFIX + preferredID(); + } + // It is necessary so the old actions (clone and close from org.openide.actions package) remain working. /** Initialized ActionMap of this TopComponent. @@ -432,6 +473,17 @@ * @deprecated Use {@link #open()} instead. */ @Deprecated public void open(Workspace workspace) { + if (isPersistLocation()) { + modeName = NbPreferences.forModule(getClass()).get(getModeIdKey(), null); + if (modeName == null) { + modeName = getClass().getAnnotation( + RetainLocation.class).value(); + } + Mode mode = WindowManager.getDefault().findMode(modeName); + if (mode != null) { + mode.dockInto(this); + } + } WindowManager.getDefault().topComponentOpen(this); }