/* * * Perforce/JBuilder Opentool * Copyright (C) 2002 Mark Ackerman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package com.dafreels.opentools.actions.ui; //JBuilder import java.io.File; import java.util.ArrayList; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import com.borland.primetime.actions.ActionGroup; import com.borland.primetime.actions.ActionToolBar; import com.borland.primetime.ide.Browser; import com.dafreels.opentools.Main; import com.dafreels.opentools.MessageWriter; import com.dafreels.opentools.actions.AddAction; import com.dafreels.vcs.command.Command; import com.dafreels.vcs.command.CommandTool; import com.dafreels.vcs.command.MessageFormatter; import com.dafreels.vcs.util.ActionImages; /** * Title: Perforce Open Tool * Description: get the history for a file * Copyright: Copyright (c) 2002 * Company: * @author Mark Ackerman * @version 1.0 */ public class NotInDepotDialog extends JDialog { private DefaultMutableTreeNode _root; private JTree _tree; private String _clientRoot; private String _depotRoot; private JPopupMenu _fileNodePopup; private JMenuItem _addFileMenuItem; private Action _addAction; private ActionGroup _addActionGroup; private ArrayList _filters; public NotInDepotDialog(Frame parent, boolean modal) { super(parent, modal); buildControls(); } protected void buildControls() { getContentPane().setLayout(new BorderLayout()); JPanel centerPanel = new JPanel(new GridBagLayout()); getContentPane().add(centerPanel, BorderLayout.CENTER); createToolbar(); createMenu(); setTitle("Files not in Depot"); _root = new DefaultMutableTreeNode(""); _tree = new JTree(_root) { public Dimension getPreferredScrollableViewportSize() { Dimension d = super.getPreferredScrollableViewportSize(); d.width = 300; return d; } public String getToolTipText(MouseEvent e) { TreePath path = _tree.getPathForLocation(e.getX(), e.getY()); if (path == null) { return null; } Object obj = path.getLastPathComponent(); if (obj instanceof FileNode) { return ((FileNode) obj).getToolTipText(); } return null; } }; _tree.setToolTipText(""); _tree.setCellRenderer(new NIDDTreeCellRenderer()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.insets = new Insets(5, 5, 0, 5); centerPanel.add(new JScrollPane(_tree), gbc); JButton button = new JButton("OK"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.SOUTH; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(5, 5, 0, 5); centerPanel.add(button, gbc); _tree.addTreeExpansionListener(new TreeExpansionListener() { public void treeCollapsed(TreeExpansionEvent e) { } public void treeExpanded(TreeExpansionEvent e) { TreePath path = e.getPath(); DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); if (!(node instanceof FolderNode)) { return; } if (node.getChildCount() == 0) { fillFolderNode(path); } } }); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); } }); _tree.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e)) { TreePath path = _tree.getPathForLocation(e.getX(), e.getY()); if (path == null) { return; } Object obj = path.getLastPathComponent(); if (obj instanceof FileNode) { FileNode fnode = (FileNode) obj; if (fnode.isInDepot()) { _addActionGroup.setEnabled(false); return; } _addActionGroup.setEnabled(true); _tree.setSelectionPath(path); JPopupMenu menu = getFileNodePopup(); menu.show(_tree, e.getX(), e.getY()); } else { _addActionGroup.setEnabled(false); } } } }); getRootPane().registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { refreshDialog(); } }, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0, true), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); getAddAction().setEnabled(false); getClientSpec(); fillRootNode(); pack(); setLocationRelativeTo(getParent()); } private void refreshDialog() { getClientSpec(); fillRootNode(); } /** * return the JPopupMenu for the FileNodes */ protected JPopupMenu getFileNodePopup() { if (_fileNodePopup == null) { _fileNodePopup = new JPopupMenu(); _addFileMenuItem = new JMenuItem(getAddAction()); _fileNodePopup.add(_addFileMenuItem); } return _fileNodePopup; } /** * */ protected void addFiles() { TreePath[] paths = _tree.getSelectionPaths(); if (paths == null) { return; } ArrayList list = new ArrayList(paths.length); TreePath path; for (int i = 0; i < paths.length; i++) { path = paths[i]; Object obj = path.getLastPathComponent(); if (!(obj instanceof FileNode)) { continue; } FileNode node = (FileNode) obj; if (node.isInDepot()) { continue; } list.add(node.getFilePath()); } AddFilesDialog dialog = new AddFilesDialog(this, true); dialog.fillForm(list); dialog.setVisible(true); if (dialog.wasCanceled()) { return; } String changeList = dialog.getChangelist(); com.dafreels.vcs.command.Command cmd = new com.dafreels.vcs.command.Command( com.dafreels.vcs.command.Command.ADD); if (changeList != null) { cmd.addPath("-c " + changeList); } cmd.addPaths(dialog.getFiles()); if (cmd.getPathCount() == 0) { return; } new AddAction(true).runCommand(Browser.getActiveBrowser(), cmd); } /** * * @return */ public Action getAddAction() { if (_addAction == null) { _addAction = new AbstractAction("Add File(s)", ActionImages.P4_ADD) { public void actionPerformed(ActionEvent e) { addFiles(); } }; //_addAction.setEnabled(false); _addAction.putValue( Action.SHORT_DESCRIPTION, "Add Selected Files to Depot"); } return _addAction; } /** * */ protected void createMenu() { JMenuBar mbar = new JMenuBar(); JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic('F'); mbar.add(fileMenu); JMenuItem closeItem = new JMenuItem("Close"); closeItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); } }); fileMenu.add(closeItem); JMenu editMenu = new JMenu("Edit"); editMenu.setMnemonic('E'); mbar.add(editMenu); JMenuItem configItem = new JMenuItem("Configure", 'C'); configItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayConfigDialog(); } }); editMenu.add(configItem); setJMenuBar(mbar); } /** * */ protected void createToolbar() { _addActionGroup = new ActionGroup(); _addActionGroup.add(getAddAction()); _addActionGroup.setEnabled(false); ActionGroup ag = new ActionGroup(); ag.add(_addActionGroup); ActionGroup ag1 = new ActionGroup(); Action noDescAction = new AbstractAction("No Descendants", ActionImages.P4_NO_DESCENDANTS) { public void actionPerformed(ActionEvent e) { } }; noDescAction.putValue(Action.SHORT_DESCRIPTION, "No Descendants"); ag1.add(noDescAction); Action immDescAction = new AbstractAction( "Immediate Descendants", ActionImages.P4_IMM_DESCENDANTS) { public void actionPerformed(ActionEvent e) { } }; immDescAction.putValue(Action.SHORT_DESCRIPTION, "Immediate Descendants"); ag1.add(immDescAction); Action allDescendants = new AbstractAction("All Descendants", ActionImages.P4_ALL_DESCENDANTS) { public void actionPerformed(ActionEvent e) { } }; allDescendants.putValue(Action.SHORT_DESCRIPTION, "All Descendants"); ag1.add(allDescendants); ag.add(ag1); ActionToolBar toolbar = new ActionToolBar(this, ag); getContentPane().add(toolbar, BorderLayout.NORTH); } /** * get the client view and depot root */ protected void getClientSpec() { CommandTool.runCommand(new Command("client -o"), Main.m_props); if (MessageFormatter.getErrorMessageCount() > 0) { MessageWriter.outputErrorMessages(MessageFormatter.getInstance()); return; } String msg; int idx; while ((msg = MessageFormatter.getNextMessage()) != null) { if (msg.startsWith("Root:")) { idx = msg.indexOf("\t"); msg = msg.substring(idx); _clientRoot = msg.trim(); } else if (msg.startsWith("View:")) { msg = MessageFormatter.getNextMessage(); if (msg == null) { return; } idx = msg.indexOf("..."); msg = msg.substring(1, idx); _depotRoot = msg; } } System.out.println("_clientRoot=" + _clientRoot); System.out.println("_depotRoot=" + _depotRoot); } public void fillRootNode() { if (_clientRoot == null || _depotRoot == null) { getClientSpec(); } _root = new DefaultMutableTreeNode(_depotRoot); fillFolderNode(_root, _depotRoot); DefaultTreeModel model = (DefaultTreeModel) _tree.getModel(); model.setRoot(_root); } protected void fillFolderNode(DefaultMutableTreeNode node, String path) { try { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); CommandTool.runCommand(new Command("dirs -C " + path + "*"), Main.m_props); if (MessageFormatter.getErrorMessageCount() > 0) { MessageWriter.outputErrorMessages(MessageFormatter.getInstance()); getFolderNodeFiles(node, path); return; } String msg; FolderNode fnode; int len = path.lastIndexOf("/"); len++; MessageFormatter.getNextMessage(); // skip the first message while ((msg = MessageFormatter.getNextMessage()) != null) { msg = msg.substring(len); fnode = new FolderNode(msg); node.add(fnode); } getFolderNodeFiles(node, path); } finally { setCursor(Cursor.getDefaultCursor()); } } /** * fill the specified node with any files in the depot * @param node * @param path */ private void getFolderNodeFiles(DefaultMutableTreeNode node, String path) { CommandTool.runCommand(new Command("fstat -C -s " + path + "*"), Main.m_props); if (MessageFormatter.getErrorMessageCount() > 0) { MessageWriter.outputErrorMessages(MessageFormatter.getInstance()); return; } String msg, file; FileNode fnode; int len = path.lastIndexOf("/"); len++; MessageFormatter.getNextMessage(); // skip the first message while ((msg = MessageFormatter.getNextMessage()) != null) { if (msg.startsWith("... depotFile")) { len = msg.lastIndexOf("/"); file = msg; msg = msg.substring(len + 1); fnode = new FileNode(msg, file, true); node.add(fnode); } } getFileSystemFiles(node, path); } /** * get the files in the file system for the path add the files that aren't in the depot * @param node * @param path */ private void getFileSystemFiles(DefaultMutableTreeNode node, String path) { path = convertDepotToFileSystemPath(path); if (path == null) { return; } File f = new File(path); String[] files = f.list(); if (files == null) { return; } int currentChildCnt = node.getChildCount(); DefaultMutableTreeNode cnode; boolean found, nodeAdded = false; String fileName, filePath; for (int i = 0; i < files.length; i++) { fileName = files[i]; if (fileName.endsWith(".class")) { continue; } found = false; for (int j = 0; j < currentChildCnt; j++) { cnode = (DefaultMutableTreeNode) node.getChildAt(j); if (cnode.getUserObject().equals(fileName)) { found = true; break; } } if (!found) { filePath = path + File.separator + fileName; cnode = new FileNode(fileName, filePath, false); node.add(cnode); nodeAdded = true; } } if (nodeAdded) { ((DefaultTreeModel) _tree.getModel()).nodeStructureChanged(node); } } /** * fill the path with the appropriate data * @param path */ protected void fillFolderNode(TreePath path) { StringBuffer buf = new StringBuffer(); String pathComponent; for (int i = 0; i < path.getPathCount(); i++) { pathComponent = path.getPathComponent(i).toString(); buf.append(pathComponent); if (!pathComponent.endsWith("/")) { buf.append("/"); } } DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); fillFolderNode(node, buf.toString()); ((DefaultTreeModel) _tree.getModel()).nodeStructureChanged(node); } private String convertDepotToFileSystemPath(String depotPath) { if (depotPath.endsWith("/")) { depotPath = depotPath.substring(0, depotPath.length() - 1); } CommandTool.runCommand(new Command("where " + depotPath), Main.m_props); if (MessageFormatter.getErrorMessageCount() > 0) { MessageWriter.outputErrorMessages(MessageFormatter.getInstance()); return null; } String msg; MessageFormatter.getNextMessage(); // skip the first message msg = MessageFormatter.getNextMessage(); if (msg == null) { return null; } int idx = msg.lastIndexOf(" "); return msg.substring(idx + 1); } protected void displayConfigDialog() { /* if ( _configDialog == null ) { _configDialog = new ConfigDialog(this, true); } _configDialog.fillForm(); _configDialog.setVisible(true); if (_configDialog.wasCanceled()) { return; } _filters = _configDialog.getFileFilters(); PerforceGroup.NOTINDEPOTFILEFILTER.setValue(Browser.getActiveBrowser().getActiveProject(), */ } /** * node that always shows as a folder * @author Mark Ackerman * */ public class FolderNode extends DefaultMutableTreeNode { public FolderNode(Object userObj) { super(userObj); } public boolean isLeaf() { return false; } } public class FileNode extends DefaultMutableTreeNode { private boolean _inDepot; private String _path; public FileNode(Object userObj, String path, boolean inDepot) { super(userObj); _inDepot = inDepot; _path = path; } public boolean isLeaf() { return true; } public String getFilePath() { return _path; } public boolean isInDepot() { return _inDepot; } public String toString() { return getUserObject().toString(); } public String getToolTipText() { return _path; } } public class NIDDTreeCellRenderer extends DefaultTreeCellRenderer { public NIDDTreeCellRenderer() { super(); } public Component getTreeCellRendererComponent( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component c = super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus); if (value instanceof FileNode) { FileNode fn = (FileNode) value; if (!fn.isInDepot()) { setForeground(Color.red); setIcon(ActionImages.P4_FILE_NOT_IN_DEPOT); } else { setIcon(ActionImages.P4_FILE_IN_DEPOT); } } return c; } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 4090 | David Freels |
Fixed bug where paths with spaces would not work. Also checked in new code or JBuilderX. |
||
#2 | 3651 | David Freels | Remove file extension limitations. | ||
#1 | 2994 | Mark E. Ackerman |
changed for version 1.0.7. Added display of submitted changelists, redo sync, updated icons, misc bug fixes and improvements. |