blob: 662284b326a5042a427489193fb063b636b1da9d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.gradle.nodes;
import org.netbeans.modules.gradle.spi.nodes.NodeUtils;
import org.netbeans.modules.gradle.NbGradleProjectImpl;
import org.netbeans.modules.gradle.api.NbGradleProject;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.netbeans.api.annotations.common.StaticResource;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.spi.project.ui.LogicalViewProvider;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.ContextAwareAction;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import static org.netbeans.modules.gradle.nodes.Bundle.*;
import java.util.Set;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.modules.gradle.api.GradleBaseProject;
import org.netbeans.modules.gradle.spi.Utils;
import org.openide.nodes.Children;
/**
*
* @author Laszlo Kishalmi
*/
public class SubProjectsNode extends AbstractNode {
@StaticResource
private static final String SP_BADGE
= "org/netbeans/modules/gradle/resources/gradle-large-badge.png";
@NbBundle.Messages("LBL_SubProjects=Sub Projects")
public SubProjectsNode(NbGradleProjectImpl proj, String path) {
super(Children.create(new SubProjectsChildFactory(proj), true));
if (":".equals(path)) { //NOI18N
setName("SubProjects"); //NOI18N
setDisplayName(LBL_SubProjects());
} else {
int colon = path.lastIndexOf(':', path.length() - 2);
String partName = path.substring(colon + 1, path.length() - 1);
setDisplayName(Utils.capitalize(partName));
setName(path);
}
}
public SubProjectsNode(NbGradleProjectImpl proj) {
this(proj, ":"); //NOI18N
}
@Override
public Action[] getActions(boolean bool) {
return new Action[]{};
}
private static Image getIcon(boolean opened) {
Image badge = ImageUtilities.loadImage(SP_BADGE, true); //NOI18N
return ImageUtilities.mergeImages(NodeUtils.getTreeFolderIcon(opened), badge, 4, 4);
}
@Override
public Image getIcon(int type) {
return getIcon(false);
}
@Override
public Image getOpenedIcon(int type) {
return getIcon(true);
}
private static class SubProjectsChildFactory extends ChildFactory<Project> {
private final Project project;
private final PropertyChangeListener listener;
SubProjectsChildFactory(Project proj) {
project = proj;
listener = (PropertyChangeEvent evt) -> {
if (NbGradleProject.PROP_PROJECT_INFO.equals(evt.getPropertyName())) {
ProjectManager.getDefault().clearNonProjectCache();
refresh(false);
}
};
NbGradleProject.addPropertyChangeListener(project, listener);
}
@Override
protected boolean createKeys(final List<Project> projects) {
Set<Project> containedProjects = ProjectUtils.getContainedProjects(project, false);
projects.addAll(containedProjects);
return true;
}
@Override
protected Node createNodeForKey(Project key) {
Set<Project> containedProjects = ProjectUtils.getContainedProjects(key, false);
GradleBaseProject gbp = GradleBaseProject.get(project);
String prefix = (gbp != null && !gbp.isRoot() ? gbp.getPath() : "") + ':';
Children ch = containedProjects.isEmpty() ? Children.LEAF : Children.create(new SubProjectsChildFactory(key), true);
return createSubProjectNode(key, prefix, ch);
}
}
public static Node createSubProjectNode(Project prj) {
return createSubProjectNode(prj, null, Children.LEAF);
}
public static Node createSubProjectNode(Project prj, String path, Children children) {
Node ret = null;
if (prj.getLookup().lookup(NbGradleProjectImpl.class) != null) {
assert prj.getLookup().lookup(LogicalViewProvider.class) != null;
Node original = prj.getLookup().lookup(LogicalViewProvider.class).createLogicalView();
ret = new ProjectFilterNode(path, original, children);
}
return ret;
}
public static class ProjectFilterNode extends FilterNode {
private final String prefix;
ProjectFilterNode(String prefix, Node original, org.openide.nodes.Children children) {
super(original, children);
this.prefix = prefix;
}
ProjectFilterNode(Node original) {
this(null, original, Children.LEAF);
}
@Override
public String getDisplayName() {
boolean usePath = super.getName().equals(super.getDisplayName());
if (usePath && (prefix != null)) {
GradleBaseProject gbp = GradleBaseProject.get(getLookup().lookup(Project.class));
if (gbp != null) {
String path = gbp.getPath();
return path.startsWith(prefix) && path.length() > prefix.length()
? path.substring(prefix.length())
: path;
}
}
return super.getDisplayName();
}
@Override
public Action[] getActions(boolean b) {
ArrayList<Action> lst = new ArrayList<Action>();
lst.add(OpenProjectAction.SINGLETON);
return lst.toArray(new Action[lst.size()]);
}
@Override
public Action getPreferredAction() {
return OpenProjectAction.SINGLETON;
}
}
private static class OpenProjectAction extends AbstractAction implements ContextAwareAction {
static final OpenProjectAction SINGLETON = new OpenProjectAction();
private OpenProjectAction() {
}
public @Override
void actionPerformed(ActionEvent e) {
assert false;
}
@NbBundle.Messages("BTN_Open_Project=Open Project")
public @Override
Action createContextAwareInstance(final Lookup context) {
return new AbstractAction(BTN_Open_Project()) {
public @Override
void actionPerformed(ActionEvent e) {
Collection<? extends NbGradleProjectImpl> projects = context.lookupAll(NbGradleProjectImpl.class);
final NbGradleProjectImpl[] projectsArray = projects.toArray(new NbGradleProjectImpl[0]);
OpenProjects.getDefault().open(projectsArray, false, true);
if (projectsArray.length > 0) {
RequestProcessor.getDefault().post(() -> {
OpenProjects.getDefault().open(projectsArray, false, true);
}, 500);
}
}
};
}
}
}