001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.mercurial.ui.clone;
042:
043: import org.netbeans.api.project.Project;
044: import org.netbeans.api.project.ProjectUtils;
045: import org.netbeans.api.project.ProjectManager;
046: import org.netbeans.spi.project.ui.support.CommonProjectActions;
047: import org.netbeans.spi.project.ui.support.ProjectChooser;
048: import org.openide.filesystems.FileUtil;
049: import org.openide.nodes.Node;
050: import org.openide.explorer.ExplorerManager;
051: import org.openide.windows.TopComponent;
052: import org.openide.windows.WindowManager;
053: import org.openide.filesystems.FileObject;
054: import java.util.logging.Level;
055: import org.netbeans.modules.mercurial.Mercurial;
056:
057: import javax.swing.*;
058: import java.awt.event.ActionEvent;
059: import java.util.List;
060: import java.util.LinkedList;
061: import java.util.Enumeration;
062: import java.util.Collections;
063: import java.io.IOException;
064: import java.io.File;
065:
066: /**
067: * Simpliied nb_all/projects/projectui/src/org/netbeans/modules/project/ui/ProjectUtilities.java,
068: * nb_all/projects/projectui/src/org/netbeans/modules/project/ui/ProjectTab.java and
069: * nb_all/ide/welcome/src/org/netbeans/modules/welcome/ui/TitlePanel.java copy.
070: *
071: * @author Petr Kuzel
072: */
073: final class ProjectUtilities {
074:
075: private static final String ProjectTab_ID_LOGICAL = "projectTabLogical_tc"; // NOI18N
076:
077: public static void selectAndExpandProject(final Project p) {
078:
079: // invoke later to select the being opened project if the focus is outside ProjectTab
080: SwingUtilities.invokeLater(new Runnable() {
081:
082: final ExplorerManager.Provider ptLogial = findDefault(ProjectTab_ID_LOGICAL);
083:
084: public void run() {
085: Node root = ptLogial.getExplorerManager()
086: .getRootContext();
087: // Node projNode = root.getChildren ().findChild( p.getProjectDirectory().getName () );
088: Node projNode = root.getChildren().findChild(
089: ProjectUtils.getInformation(p).getName());
090: if (projNode != null) {
091: try {
092: ptLogial.getExplorerManager().setSelectedNodes(
093: new Node[] { projNode });
094: } catch (Exception ignore) {
095: // may ignore it
096: }
097: }
098: }
099: });
100:
101: }
102:
103: /* Singleton accessor. As ProjectTab is persistent singleton this
104: * accessor makes sure that ProjectTab is deserialized by window system.
105: * Uses known unique TopComponent ID TC_ID = "projectTab_tc" to get ProjectTab instance
106: * from window system. "projectTab_tc" is name of settings file defined in module layer.
107: * For example ProjectTabAction uses this method to create instance if necessary.
108: */
109: private static synchronized ExplorerManager.Provider findDefault(
110: String tcID) {
111: TopComponent tc = WindowManager.getDefault().findTopComponent(
112: tcID);
113: return (ExplorerManager.Provider) tc;
114: }
115:
116: /**
117: * Runs <i>New Project...</i> wizard with redefined defaults:
118: * <ul>
119: * <li>default project directory to working folder to
120: * capture creating new project in placeholder
121: * directory prepared by CVS server admin
122: * <li>CommonProjectActions.EXISTING_SOURCES_FOLDER
123: * pointing to working folder to capture
124: * typical <i>... from Existing Sources</i> panel
125: * <i>Add</i> button behaviour.
126: * </ul>
127: */
128: public static void newProjectWizard(File workingDirectory) {
129: if (workingDirectory == null)
130: return;
131:
132: Action action = CommonProjectActions.newProjectAction();
133: if (action != null) {
134: File original = ProjectChooser.getProjectsFolder();
135: ProjectChooser.setProjectsFolder(workingDirectory);
136: FileObject workingFolder = FileUtil
137: .toFileObject(workingDirectory);
138: action.putValue(
139: CommonProjectActions.EXISTING_SOURCES_FOLDER,
140: workingFolder);
141: performAction(action);
142: try {
143: ProjectChooser.setProjectsFolder(original);
144: } catch (IllegalArgumentException e) {
145: // it seems the original folder is invalid, ignore this
146: }
147: }
148: }
149:
150: /**
151: * Scans given folder (and subfolder into deep 5) for projects.
152: * @return List of {@link Project}s never <code>null</code>.
153: */
154: public static List<Project> scanForProjects(FileObject scanRoot) {
155: ProjectManager.getDefault().clearNonProjectCache();
156: return scanForProjectsRecursively(scanRoot, 5);
157: }
158:
159: private static List<Project> scanForProjectsRecursively(
160: FileObject scanRoot, int deep) {
161: if (scanRoot == null || deep <= 0)
162: return Collections.emptyList();
163: List<Project> projects = new LinkedList<Project>();
164: ProjectManager projectManager = ProjectManager.getDefault();
165: if (scanRoot.isFolder() && projectManager.isProject(scanRoot)) {
166: try {
167: Project prj = projectManager.findProject(scanRoot);
168: if (prj != null) {
169: projects.add(prj);
170: }
171: } catch (IOException e) {
172: // it happens for all apisupport projects unless
173: // checked out into directory that contains nbbuild and openide folders
174: // apisupport project is valid only if placed in defined directory structure
175: Throwable cause = new Throwable(
176: "HG.PU: ignoring suspicious project folder..."); // NOI18N
177: e.initCause(cause);
178: Mercurial.LOG.log(Level.INFO, null, e);
179: }
180: }
181: Enumeration en = scanRoot.getChildren(false);
182: while (en.hasMoreElements()) {
183: FileObject fo = (FileObject) en.nextElement();
184: if (fo.isFolder()) {
185: List<Project> nested = scanForProjectsRecursively(fo,
186: deep - 1); // RECURSION
187: projects.addAll(nested);
188: }
189: }
190: return projects;
191: }
192:
193: private static boolean performAction(Action a) {
194: if (a == null) {
195: return false;
196: }
197: ActionEvent ae = new ActionEvent(ProjectUtilities.class,
198: ActionEvent.ACTION_PERFORMED, "command"); // NOI18N
199: try {
200: a.actionPerformed(ae);
201: return true;
202: } catch (Exception e) {
203: Mercurial.LOG.log(Level.WARNING, null, e);
204: return false;
205: }
206: }
207:
208: }
|