package ctagsinterface.projects; import java.awt.GridBagConstraints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Vector; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.gjt.sp.jedit.AbstractOptionPane; import org.gjt.sp.jedit.GUIUtilities; import org.gjt.sp.jedit.OptionGroup; import org.gjt.sp.jedit.OptionPane; import org.gjt.sp.jedit.jEdit; import org.gjt.sp.jedit.gui.RolloverButton; import projectviewer.ProjectManager; import projectviewer.config.OptionsService; import projectviewer.vpt.VPTProject; import ctagsinterface.index.TagIndex; import ctagsinterface.main.CtagsInterfacePlugin; import ctagsinterface.index.TagIndex.OriginType; @SuppressWarnings("serial") public class ProjectDependencies extends AbstractOptionPane { // TODO: single file dependency private static final String PROJECT_DEPENDENCY = "projectDependency"; private static final String TREE_DEPENDENCY = "treeDependency"; private static final String TAGFILE_DEPENDENCY = "tagFileDependency"; JList projects; JList trees; JList tagFiles; DefaultListModel projectsModel; DefaultListModel treesModel; DefaultListModel tagFilesModel; VPTProject project; public ProjectDependencies(VPTProject project) { super("CtagsInterface-ProjectDependencies"); this.project = project; } private interface DependencyAsker { String getDependency(); } protected void _init() { refreshDependencies(); projectsModel = getListModel(PROJECT_DEPENDENCY); projects = createList("Projects:", projectsModel, new DependencyAsker () { public String getDependency() { return showProjectSelectionDialog(); } }); addSeparator(); treesModel = getListModel(TREE_DEPENDENCY); trees = createList("Trees:", treesModel, new DependencyAsker () { public String getDependency() { return showSourceTreeSelectionDialog(); } }); addSeparator(); tagFilesModel = getListModel(TAGFILE_DEPENDENCY); tagFiles = createList("Tag files:", tagFilesModel, new DependencyAsker () { public String getDependency() { return showTagFileSelectionDialog(); } }); } private void refreshDependencies() { refreshDependency(PROJECT_DEPENDENCY, OriginType.PROJECT); refreshDependency(TREE_DEPENDENCY, OriginType.DIRECTORY); refreshDependency(TAGFILE_DEPENDENCY, OriginType.TAGFILE); } private void refreshDependency(String dependencyType, OriginType originType) { Vector <String> origins = new Vector<String>(); CtagsInterfacePlugin.getIndex().getOrigins(originType, origins); Vector <String> dependencies = getListProperty(dependencyType); dependencies.retainAll(origins); setListProperty(dependencyType, dependencies); } private void setListModel(String propertyName, DefaultListModel model) { Vector<String> list = new Vector<String>(); for (int i = 0; i < model.size(); i++) list.add((String) model.getElementAt(i)); setListProperty(propertyName, list); } private DefaultListModel getListModel(String propertyName) { Vector<String> list = getListProperty(propertyName); DefaultListModel model = new DefaultListModel(); for (int i = 0; i < list.size(); i++) model.addElement(list.get(i)); return model; } private Vector<String> getListProperty(String propertyName) { return getListProperty(project, propertyName); } private void setListProperty(String propertyName, Vector<String> list) { for (int i = 0; i < list.size(); i++) project.setProperty(propertyName + i, list.get(i)); for (int i = list.size(); true; i++) { String prop = propertyName + i; if (project.getProperty(prop) == null) break; project.removeProperty(prop); } } private JList createList(String title, final DefaultListModel model, final DependencyAsker da) { addComponent(new JLabel(title)); final JList list = new JList(model); addComponent(new JScrollPane(list), GridBagConstraints.HORIZONTAL); JPanel buttons = new JPanel(); JButton add = new RolloverButton(GUIUtilities.loadIcon("Plus.png")); add.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String s = da.getDependency(); if (s != null && !s.equals("") && !model.contains(s)) { int index = list.getSelectedIndex(); model.add(index + 1, s); list.setSelectedIndex(index + 1); } } }); JButton remove = new RolloverButton(GUIUtilities.loadIcon("Minus.png")); remove.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int index = list.getSelectedIndex(); if (index >= 0) { model.removeElementAt(index); if (index < model.size()) list.setSelectedIndex(index); else if (! model.isEmpty()) list.setSelectedIndex(model.size() - 1); } } }); buttons.add(add); buttons.add(remove); addComponent(buttons); return list; } private String showProjectSelectionDialog() { ProjectWatcher pw = CtagsInterfacePlugin.getProjectWatcher(); if (pw == null) { JOptionPane.showMessageDialog(this, jEdit.getProperty( "messages.CtagsInterface.noPVSupport")); return null; } String project = pw.getActiveProject(jEdit.getActiveView()); Vector<String> nameVec = CtagsInterfacePlugin.getIndex().getOrigins(OriginType.PROJECT); nameVec.remove(project); return getSelectionDialog(nameVec, projectsModel, "Project"); } private String showSourceTreeSelectionDialog() { Vector<String> dirsVec = CtagsInterfacePlugin.getIndex().getOrigins(OriginType.DIRECTORY); return getSelectionDialog(dirsVec, treesModel, "Source tree"); } private String showTagFileSelectionDialog() { Vector<String> tagFilesVec = CtagsInterfacePlugin.getIndex().getOrigins(OriginType.TAGFILE); return getSelectionDialog(tagFilesVec, tagFilesModel, "Tag file"); } private String getSelectionDialog(Vector<String> nameVec, DefaultListModel listModel, String label) { String selected = ""; Object [] listItems = listModel.toArray(); for (int i = 0; i < listItems.length; i++) { nameVec.remove(listItems[i].toString()); } if (nameVec.size()>0) { String [] names = new String[nameVec.size()]; nameVec.toArray(names); selected = (String) JOptionPane.showInputDialog(this, "Select a "+ label.toLowerCase()+":", label+"s", JOptionPane.QUESTION_MESSAGE, null, names, names[0]); } else { String other = listModel.size()>0 ? "other " : ""; JOptionPane.showMessageDialog(this, "No " + other + label.toLowerCase() +"s available."); } return selected; } protected void _save() { setListModel(PROJECT_DEPENDENCY, projectsModel); setListModel(TREE_DEPENDENCY, treesModel); setListModel(TAGFILE_DEPENDENCY, tagFilesModel); } public static Vector<String> getListProperty(VPTProject project, String propertyName) { Vector<String> list = new Vector<String>(); int i = 0; while (true) { String value = project.getProperty(propertyName + i); if (value == null) break; list.add(value); i++; } return list; } public static HashMap<String, Vector<String>> getDependencies(String projectName) { HashMap<String, Vector<String>> map = new HashMap<String, Vector<String>>(); VPTProject project = ProjectManager.getInstance().getProject(projectName); if (project == null) return map; Vector<String> projectDeps = getListProperty(project, PROJECT_DEPENDENCY); map.put(TagIndex.OriginType.PROJECT.name, projectDeps); Vector<String> treeDeps = getListProperty(project, TREE_DEPENDENCY); map.put(TagIndex.OriginType.DIRECTORY.name, treeDeps); Vector<String> tagFileDeps = getListProperty(project, TAGFILE_DEPENDENCY); map.put(TagIndex.OriginType.TAGFILE.name, tagFileDeps); return map; } public static class ProjectDependencyOptionService implements OptionsService { public OptionGroup getOptionGroup(VPTProject proj) { return null; } public OptionPane getOptionPane(VPTProject proj) { return new ProjectDependencies(proj); } } }