1 19 20 package org.netbeans.modules.apisupport.project.ui; 21 22 import java.awt.EventQueue ; 23 import java.awt.Image ; 24 import java.awt.event.ActionEvent ; 25 import java.beans.PropertyChangeEvent ; 26 import java.beans.PropertyChangeListener ; 27 import java.io.IOException ; 28 import java.util.Collections ; 29 import java.util.SortedSet ; 30 import java.util.TreeSet ; 31 import javax.swing.AbstractAction ; 32 import javax.swing.Action ; 33 import javax.swing.event.ChangeEvent ; 34 import javax.swing.event.ChangeListener ; 35 import org.netbeans.api.project.Project; 36 import org.netbeans.api.project.ProjectInformation; 37 import org.netbeans.api.project.ProjectManager; 38 import org.netbeans.api.project.ProjectUtils; 39 import org.netbeans.api.project.ui.OpenProjects; 40 import org.netbeans.modules.apisupport.project.NbModuleProject; 41 import org.netbeans.modules.apisupport.project.Util; 42 import org.netbeans.modules.apisupport.project.suite.SuiteProject; 43 import org.netbeans.modules.apisupport.project.ui.customizer.SuiteUtils; 44 import org.netbeans.modules.apisupport.project.ui.wizard.NewNbModuleWizardIterator; 45 import org.netbeans.spi.project.SubprojectProvider; 46 import org.netbeans.spi.project.ui.support.NodeFactory; 47 import org.netbeans.spi.project.ui.support.NodeFactorySupport; 48 import org.netbeans.spi.project.ui.support.NodeList; 49 import org.openide.DialogDisplayer; 50 import org.openide.ErrorManager; 51 import org.openide.NotifyDescriptor; 52 import org.openide.awt.StatusDisplayer; 53 import org.openide.nodes.AbstractNode; 54 import org.openide.nodes.Children; 55 import org.openide.nodes.Node; 56 import org.openide.util.HelpCtx; 57 import org.openide.util.NbBundle; 58 import org.openide.util.RequestProcessor; 59 import org.openide.util.Utilities; 60 import org.openide.util.actions.CookieAction; 61 import org.openide.util.actions.NodeAction; 62 import org.openide.util.lookup.Lookups; 63 import org.openide.windows.WindowManager; 64 65 69 public class ModulesNodeFactory implements NodeFactory { 70 71 72 public ModulesNodeFactory() { 73 } 74 75 public NodeList createNodes(Project p) { 76 SuiteProject prj = p.getLookup().lookup(SuiteProject.class); 77 assert prj != null; 78 return NodeFactorySupport.fixedNodeList(new ModulesNode(prj)); 79 } 80 81 private static String getMessage(final String key) { 82 return NbBundle.getMessage(SuiteLogicalView.class, key); 83 } 84 85 86 87 static final class ModulesNode extends AbstractNode { 88 89 private SuiteProject suite; 90 91 ModulesNode(final SuiteProject suite) { 92 super(new ModuleChildren(suite)); 93 this.suite = suite; 94 setName("modules"); setDisplayName(getMessage("CTL_Modules")); 96 } 97 98 public Action [] getActions(boolean context) { 99 return new Action [] { 100 new AddNewSuiteComponentAction(suite), 101 new AddNewLibraryWrapperAction(suite), 102 new AddSuiteComponentAction(suite), 103 }; 104 } 105 106 private Image getIcon(boolean opened) { 107 Image badge = Utilities.loadImage("org/netbeans/modules/apisupport/project/suite/resources/module-badge.gif", true); 108 return Utilities.mergeImages(UIUtil.getTreeFolderIcon(opened), badge, 9, 9); 109 } 110 111 public Image getIcon(int type) { 112 return getIcon(false); 113 } 114 115 public Image getOpenedIcon(int type) { 116 return getIcon(true); 117 } 118 119 static final class ModuleChildren extends Children.Keys<NbModuleProject> implements ChangeListener { 120 121 private final SuiteProject suite; 122 123 public ModuleChildren(SuiteProject suite) { 124 suite.getLookup().lookup(SubprojectProvider.class).addChangeListener(this); 125 this.suite = suite; 126 } 127 128 protected void addNotify() { 129 updateKeys(); 130 } 131 132 private void updateKeys() { 133 EventQueue.invokeLater(new Runnable () { 139 public void run() { 140 SortedSet <NbModuleProject> subModules = new TreeSet (Util.projectDisplayNameComparator()); 142 subModules.addAll(SuiteUtils.getSubProjects(suite)); 143 setKeys(subModules); 144 } 145 }); 146 } 147 148 protected void removeNotify() { 149 suite.getLookup().lookup(SubprojectProvider.class).removeChangeListener(this); 150 setKeys(Collections.EMPTY_SET); 151 } 152 153 protected Node[] createNodes(NbModuleProject p) { 154 return new Node[] {new SuiteComponentNode(p)}; 155 } 156 157 public void stateChanged(ChangeEvent ev) { 158 updateKeys(); 159 } 160 161 } 162 163 } 164 165 private static final class AddSuiteComponentAction extends AbstractAction { 166 167 private final SuiteProject suite; 168 169 public AddSuiteComponentAction(final SuiteProject suite) { 170 super(getMessage("CTL_AddModule")); 171 this.suite = suite; 172 } 173 174 public void actionPerformed(ActionEvent evt) { 175 NbModuleProject project = UIUtil.chooseSuiteComponent( 176 WindowManager.getDefault().getMainWindow(), 177 suite); 178 if (project != null) { 179 if (!SuiteUtils.contains(suite, project)) { 180 try { 181 SuiteUtils.addModule(suite, (NbModuleProject) project); 182 ProjectManager.getDefault().saveProject(suite); 183 } catch (IOException ex) { 184 ErrorManager.getDefault().notify(ex); 185 } 186 } else { 187 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( 188 NbBundle.getMessage(SuiteLogicalView.class, "MSG_SuiteAlreadyContainsCNB", project.getCodeNameBase()))); 189 } 190 } 191 } 192 193 } 194 195 private static final class AddNewSuiteComponentAction extends AbstractAction { 196 197 private final SuiteProject suite; 198 199 public AddNewSuiteComponentAction(final SuiteProject suite) { 200 super(getMessage("CTL_AddNewModule")); 201 this.suite = suite; 202 } 203 204 public void actionPerformed(ActionEvent evt) { 205 NewNbModuleWizardIterator iterator = NewNbModuleWizardIterator.createSuiteComponentIterator(suite); 206 UIUtil.runProjectWizard(iterator, "CTL_NewModuleProject"); } 208 209 } 210 211 static final class AddNewLibraryWrapperAction extends AbstractAction { 212 213 private final Project suiteProvider; 214 private final NbModuleProject target; 215 216 public AddNewLibraryWrapperAction(final Project suiteProvider, final NbModuleProject target) { 217 super(getMessage("CTL_AddNewLibrary")); 218 this.suiteProvider = suiteProvider; 219 this.target = target; 220 } 221 222 public AddNewLibraryWrapperAction(final Project suiteProvider) { 223 this(suiteProvider, null); 224 } 225 226 public void actionPerformed(ActionEvent evt) { 227 NbModuleProject project = UIUtil.runLibraryWrapperWizard(suiteProvider); 228 if (project != null && target != null) { 229 try { 230 Util.addDependency(target, project); 231 ProjectManager.getDefault().saveProject(target); 232 } catch (IOException e) { 233 assert false : e; 234 } 235 } 236 } 237 238 } 239 240 241 private static final class SuiteComponentNode extends AbstractNode { 242 243 private final static Action REMOVE_ACTION = new RemoveSuiteComponentAction(); 244 private final static Action OPEN_ACTION = new OpenProjectAction(); 245 246 public SuiteComponentNode(final NbModuleProject suiteComponent) { 247 super(Children.LEAF, Lookups.fixed(new Object [] {suiteComponent})); 248 ProjectInformation info = ProjectUtils.getInformation(suiteComponent); 249 setName(info.getName()); 250 setDisplayName(info.getDisplayName()); 251 setIconBaseWithExtension(NbModuleProject.NB_PROJECT_ICON_PATH); 252 info.addPropertyChangeListener(new PropertyChangeListener () { 253 public void propertyChange(PropertyChangeEvent evt) { 254 if (evt.getPropertyName() == ProjectInformation.PROP_DISPLAY_NAME) { 255 SuiteComponentNode.this.setDisplayName((String ) evt.getNewValue()); 256 } else if (evt.getPropertyName() == ProjectInformation.PROP_NAME) { 257 SuiteComponentNode.this.setName((String ) evt.getNewValue()); 258 } 259 } 260 }); 261 } 262 263 public Action [] getActions(boolean context) { 264 return new Action [] { 265 OPEN_ACTION, REMOVE_ACTION 266 }; 267 } 268 269 public Action getPreferredAction() { 270 return OPEN_ACTION; 271 } 272 273 } 274 275 private static final class RemoveSuiteComponentAction extends NodeAction { 276 277 protected void performAction(Node[] activatedNodes) { 278 for (int i = 0; i < activatedNodes.length; i++) { 279 final NbModuleProject suiteComponent = 280 (NbModuleProject) activatedNodes[i].getLookup().lookup(NbModuleProject.class); 281 assert suiteComponent != null : "NbModuleProject in lookup"; try { 283 NbModuleProject[] modules = SuiteUtils.getDependentModules(suiteComponent); 284 boolean remove = true; 285 if (modules.length > 0) { 286 StringBuffer sb = new StringBuffer ("<ul>"); for (int j = 0; j < modules.length; j++) { 288 sb.append("<li>" + ProjectUtils.getInformation(modules[j]).getDisplayName() + "</li>"); } 290 sb.append("</ul>"); String displayName = ProjectUtils.getInformation(suiteComponent).getDisplayName(); 292 String confirmMessage = NbBundle.getMessage(SuiteLogicalView.class, 293 "MSG_RemovingModuleMessage", displayName, sb.toString()); remove = UIUtil.showAcceptCancelDialog( 295 NbBundle.getMessage(SuiteLogicalView.class, "CTL_RemovingModuleTitle", displayName), 296 confirmMessage, getMessage("CTL_RemoveDependency"), null, NotifyDescriptor.QUESTION_MESSAGE); 297 } 298 if (remove) { 299 SuiteUtils.removeModuleFromSuiteWithDependencies(suiteComponent); 300 } 301 } catch (IOException ex) { 302 ErrorManager.getDefault().notify(ex); 303 } 304 } 305 } 306 307 protected boolean enable(Node[] activatedNodes) { 308 return true; 309 } 310 311 public String getName() { 312 return getMessage("CTL_RemoveModule"); 313 } 314 315 public HelpCtx getHelpCtx() { 316 return HelpCtx.DEFAULT_HELP; 317 } 318 319 protected boolean asynchronous() { 320 return false; 321 } 322 323 } 324 325 private static final class OpenProjectAction extends CookieAction { 326 327 protected void performAction(Node[] activatedNodes) { 328 final Project[] projects = new Project[activatedNodes.length]; 329 for (int i = 0; i < activatedNodes.length; i++) { 330 Project project = (Project) activatedNodes[i].getLookup().lookup(Project.class); 331 projects[i] = project; 332 } 333 RequestProcessor.getDefault().post(new Runnable () { 334 public void run() { 335 StatusDisplayer.getDefault().setStatusText(getMessage("MSG_OpeningProjects")); 336 OpenProjects.getDefault().open(projects, false); 337 } 338 }); 339 } 340 341 public String getName() { 342 return getMessage("CTL_OpenProject"); 343 } 344 345 public HelpCtx getHelpCtx() { 346 return HelpCtx.DEFAULT_HELP; 347 } 348 349 protected boolean asynchronous() { 350 return false; 351 } 352 353 protected int mode() { 354 return CookieAction.MODE_ALL; 355 } 356 357 protected Class [] cookieClasses() { 358 return new Class [] { Project.class }; 359 } 360 361 } 362 363 } 364 | Popular Tags |