1 19 20 package org.netbeans.modules.ruby.railsprojects.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.modules.ruby.railsprojects.GenerateAction; 33 import org.netbeans.modules.ruby.railsprojects.Generator; 34 import org.netbeans.api.project.Project; 35 import org.netbeans.api.project.ProjectUtils; 36 import org.netbeans.api.project.SourceGroup; 37 import org.netbeans.api.project.Sources; 38 import org.netbeans.modules.ruby.railsprojects.RailsProject; 39 import org.netbeans.modules.ruby.railsprojects.ui.customizer.CustomizerProviderImpl; 40 import org.netbeans.spi.project.ui.support.NodeFactory; 41 import org.netbeans.spi.project.ui.support.NodeList; 42 import org.openide.filesystems.FileObject; 43 import org.openide.nodes.AbstractNode; 44 import org.openide.nodes.FilterNode; 45 import org.openide.nodes.Node; 46 import org.openide.util.NbBundle; 47 import org.openide.util.lookup.Lookups; 48 49 53 public final class SourceNodeFactory implements NodeFactory { 54 public SourceNodeFactory() { 55 } 56 57 public NodeList createNodes(Project p) { 58 RailsProject project = (RailsProject)p.getLookup().lookup(RailsProject.class); 59 assert project != null; 60 return new SourcesNodeList(project); 61 } 62 63 private static class SourcesNodeList implements NodeList<SourceGroupKey>, ChangeListener { 64 65 private RailsProject project; 66 67 private List <ChangeListener > listeners = new ArrayList <ChangeListener >(); 68 69 public SourcesNodeList(RailsProject proj) { 70 project = proj; 71 } 72 73 public List <SourceGroupKey> keys() { 74 if (this.project.getProjectDirectory() == null || !this.project.getProjectDirectory().isValid()) { 75 return Collections.EMPTY_LIST; 76 } 77 85 Sources sources = getSources(); 86 SourceGroup[] groups = sources.getSourceGroups(RailsProject.SOURCES_TYPE_RUBY); 87 List result = new ArrayList (groups.length); 89 for( int i = 0; i < groups.length; i++ ) { 90 result.add(new SourceGroupKey(groups[i], getGenerator(groups[i].getName()))); 91 } 92 93 return result; 94 } 95 96 private Generator getGenerator(String subdir) { 97 if (subdir.equals("app/controllers")) { 98 return Generator.controller; 99 } 100 if (subdir.equals("app/views")) { 101 return Generator.controller; 102 } 103 if (subdir.equals("app/models")) { 104 return Generator.model; 105 } 106 if (subdir.equals("db")) { 107 return Generator.migration; 108 } 109 return Generator.NONE; 110 } 111 112 public synchronized void addChangeListener(ChangeListener l) { 113 listeners.add(l); 114 } 115 116 public synchronized void removeChangeListener(ChangeListener l) { 117 listeners.remove(l); 118 } 119 120 private void fireChange() { 121 ArrayList <ChangeListener > list = new ArrayList <ChangeListener >(); 122 synchronized (this) { 123 list.addAll(listeners); 124 } 125 Iterator <ChangeListener > it = list.iterator(); 126 while (it.hasNext()) { 127 ChangeListener elem = it.next(); 128 elem.stateChanged(new ChangeEvent ( this )); 129 } 130 } 131 132 public Node node(SourceGroupKey key) { 133 return new PackageViewFilterNode(key.group, key.generator, project); 134 } 135 136 public void addNotify() { 137 getSources().addChangeListener(this); 138 } 139 140 public void removeNotify() { 141 getSources().removeChangeListener(this); 142 } 143 144 public void stateChanged(ChangeEvent e) { 145 SwingUtilities.invokeLater(new Runnable () { 148 public void run() { 149 fireChange(); 150 } 151 }); 152 } 153 154 private Sources getSources() { 155 return ProjectUtils.getSources(project); 156 } 157 158 } 159 160 private static class SourceGroupKey { 161 162 public final SourceGroup group; 163 public final FileObject fileObject; 164 public final Generator generator; 165 166 SourceGroupKey(SourceGroup group, Generator generator) { 167 this.group = group; 168 this.fileObject = group.getRootFolder(); 169 this.generator = generator; 170 } 171 172 public int hashCode() { 173 return fileObject.hashCode(); 174 } 175 176 public boolean equals(Object obj) { 177 if (!(obj instanceof SourceGroupKey)) { 178 return false; 179 } else { 180 SourceGroupKey otherKey = (SourceGroupKey) obj; 181 String thisDisplayName = this.group.getDisplayName(); 182 String otherDisplayName = otherKey.group.getDisplayName(); 183 return fileObject.equals(otherKey.fileObject) && 185 thisDisplayName == null ? otherDisplayName == null : thisDisplayName.equals(otherDisplayName); 186 } 187 } 188 } 189 190 196 private static final class RootNode extends FilterNode { 198 private SourceGroup sourceGroup; 199 200 private RootNode (SourceGroup group, Generator generator) { 201 super(getOriginalNode(group, generator)); 203 this.sourceGroup = group; 204 } 206 207 213 private static Node getOriginalNode(SourceGroup group, Generator generator) { 214 FileObject root = group.getRootFolder(); 215 if ( root == null || !root.isValid()) { 218 return new AbstractNode (Children.LEAF, Lookups.singleton(Generator.NONE)); 219 } 220 return new TreeRootNode(group, generator); 225 } 230 } 231 232 233 234 236 private static class PackageViewFilterNode extends FilterNode { 237 238 private String nodeName; 239 private Project project; 240 241 Action [] actions; 242 243 public PackageViewFilterNode(SourceGroup sourceGroup, Generator generator, Project project) { 244 super(new RootNode(sourceGroup, generator)); 246 247 this.project = project; 248 this.nodeName = "Sources"; 249 } 250 251 252 public Action [] getActions(boolean context) { 253 if (!context) { 254 if (actions == null) { 255 Action superActions[] = super.getActions(context); 256 actions = new Action [superActions.length + 2]; 257 System.arraycopy(superActions, 0, actions, 0, superActions.length); 258 actions[superActions.length] = null; 259 actions[superActions.length + 1] = new PreselectPropertiesAction(project, nodeName); 260 } 261 return actions; 262 } else { 263 return super.getActions(context); 264 } 265 } 266 267 } 268 269 270 272 static class PreselectPropertiesAction extends AbstractAction { 273 274 private final Project project; 275 private final String nodeName; 276 private final String panelName; 277 278 public PreselectPropertiesAction(Project project, String nodeName) { 279 this(project, nodeName, null); 280 } 281 282 public PreselectPropertiesAction(Project project, String nodeName, String panelName) { 283 super(NbBundle.getMessage(SourceNodeFactory.class, "LBL_Properties_Action")); 284 this.project = project; 285 this.nodeName = nodeName; 286 this.panelName = panelName; 287 } 288 289 public void actionPerformed(ActionEvent e) { 290 CustomizerProviderImpl cp = (CustomizerProviderImpl) project.getLookup().lookup(CustomizerProviderImpl.class); 292 if (cp != null) { 293 cp.showCustomizer(nodeName, panelName); 294 } 295 296 } 297 } 298 299 } 300 | Popular Tags |