1 19 20 package org.netbeans.modules.ruby.rubyproject.ui; 21 22 import java.awt.event.ActionEvent ; 23 import java.util.ArrayList ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import javax.swing.AbstractAction ; 28 import javax.swing.Action ; 29 import javax.swing.SwingUtilities ; 30 import javax.swing.event.ChangeEvent ; 31 import javax.swing.event.ChangeListener ; 32 import org.netbeans.api.project.Project; 33 import org.netbeans.api.project.ProjectUtils; 34 import org.netbeans.api.project.SourceGroup; 35 import org.netbeans.api.project.Sources; 36 import org.netbeans.modules.ruby.rubyproject.RubyProject; 37 import org.netbeans.modules.ruby.rubyproject.ui.customizer.CustomizerProviderImpl; 38 import org.netbeans.spi.project.ui.support.NodeFactorySupport; 39 import org.netbeans.spi.project.ui.support.NodeFactory; 40 import org.netbeans.spi.project.ui.support.NodeList; 41 import org.openide.filesystems.FileObject; 42 import org.openide.nodes.AbstractNode; 43 import org.openide.nodes.FilterNode; 44 import org.openide.nodes.Node; 45 import org.openide.util.NbBundle; 46 47 51 public final class SourceNodeFactory implements NodeFactory { 52 public SourceNodeFactory() { 53 } 54 55 public NodeList createNodes(Project p) { 56 RubyProject project = (RubyProject)p.getLookup().lookup(RubyProject.class); 57 assert project != null; 58 return new SourcesNodeList(project); 59 } 60 61 private static class SourcesNodeList implements NodeList<SourceGroupKey>, ChangeListener { 62 63 private RubyProject project; 64 65 private List <ChangeListener > listeners = new ArrayList <ChangeListener >(); 66 67 public SourcesNodeList(RubyProject proj) { 68 project = proj; 69 } 70 71 public List <SourceGroupKey> keys() { 72 if (this.project.getProjectDirectory() == null || !this.project.getProjectDirectory().isValid()) { 73 return Collections.EMPTY_LIST; 74 } 75 Sources sources = getSources(); 76 SourceGroup[] groups = sources.getSourceGroups(RubyProject.SOURCES_TYPE_RUBY); 77 List result = new ArrayList (groups.length); 79 for( int i = 0; i < groups.length; i++ ) { 80 result.add(new SourceGroupKey(groups[i])); 81 } 82 return result; 83 } 84 85 public synchronized void addChangeListener(ChangeListener l) { 86 listeners.add(l); 87 } 88 89 public synchronized void removeChangeListener(ChangeListener l) { 90 listeners.remove(l); 91 } 92 93 private void fireChange() { 94 ArrayList <ChangeListener > list = new ArrayList <ChangeListener >(); 95 synchronized (this) { 96 list.addAll(listeners); 97 } 98 Iterator <ChangeListener > it = list.iterator(); 99 while (it.hasNext()) { 100 ChangeListener elem = it.next(); 101 elem.stateChanged(new ChangeEvent ( this )); 102 } 103 } 104 105 public Node node(SourceGroupKey key) { 106 return new PackageViewFilterNode(key.group, project); 107 } 108 109 public void addNotify() { 110 getSources().addChangeListener(this); 111 } 112 113 public void removeNotify() { 114 getSources().removeChangeListener(this); 115 } 116 117 public void stateChanged(ChangeEvent e) { 118 SwingUtilities.invokeLater(new Runnable () { 121 public void run() { 122 fireChange(); 123 } 124 }); 125 } 126 127 private Sources getSources() { 128 return ProjectUtils.getSources(project); 129 } 130 131 } 132 133 private static class SourceGroupKey { 134 135 public final SourceGroup group; 136 public final FileObject fileObject; 137 138 SourceGroupKey(SourceGroup group) { 139 this.group = group; 140 this.fileObject = group.getRootFolder(); 141 } 142 143 public int hashCode() { 144 return fileObject.hashCode(); 145 } 146 147 public boolean equals(Object obj) { 148 if (!(obj instanceof SourceGroupKey)) { 149 return false; 150 } else { 151 SourceGroupKey otherKey = (SourceGroupKey) obj; 152 String thisDisplayName = this.group.getDisplayName(); 153 String otherDisplayName = otherKey.group.getDisplayName(); 154 return fileObject.equals(otherKey.fileObject) && 156 thisDisplayName == null ? otherDisplayName == null : thisDisplayName.equals(otherDisplayName); 157 } 158 } 159 160 } 161 162 168 private static final class RootNode extends FilterNode { 170 private SourceGroup sourceGroup; 171 172 private RootNode (SourceGroup group) { 173 super(getOriginalNode(group)); 174 this.sourceGroup = group; 175 } 177 178 184 private static Node getOriginalNode(SourceGroup group) { 185 FileObject root = group.getRootFolder(); 186 if ( root == null || !root.isValid()) { 189 return new AbstractNode (Children.LEAF); 190 } 191 return new TreeRootNode(group); 196 } 201 } 202 203 204 205 207 private static class PackageViewFilterNode extends FilterNode { 208 209 private String nodeName; 210 private Project project; 211 212 Action [] actions; 213 214 public PackageViewFilterNode(SourceGroup sourceGroup, Project project) { 215 super(new RootNode(sourceGroup)); 217 218 this.project = project; 219 this.nodeName = "Sources"; 220 } 221 222 223 public Action [] getActions(boolean context) { 224 if (!context) { 225 if (actions == null) { 226 Action superActions[] = super.getActions(context); 227 actions = new Action [superActions.length + 2]; 228 System.arraycopy(superActions, 0, actions, 0, superActions.length); 229 actions[superActions.length] = null; 230 actions[superActions.length + 1] = new PreselectPropertiesAction(project, nodeName); 231 } 232 return actions; 233 } else { 234 return super.getActions(context); 235 } 236 } 237 238 } 239 240 241 243 static class PreselectPropertiesAction extends AbstractAction { 244 245 private final Project project; 246 private final String nodeName; 247 private final String panelName; 248 249 public PreselectPropertiesAction(Project project, String nodeName) { 250 this(project, nodeName, null); 251 } 252 253 public PreselectPropertiesAction(Project project, String nodeName, String panelName) { 254 super(NbBundle.getMessage(SourceNodeFactory.class, "LBL_Properties_Action")); 255 this.project = project; 256 this.nodeName = nodeName; 257 this.panelName = panelName; 258 } 259 260 public void actionPerformed(ActionEvent e) { 261 CustomizerProviderImpl cp = (CustomizerProviderImpl) project.getLookup().lookup(CustomizerProviderImpl.class); 263 if (cp != null) { 264 cp.showCustomizer(nodeName, panelName); 265 } 266 267 } 268 } 269 270 } 271 | Popular Tags |