/*
*
* 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 com.borland.primetime.*;
import com.borland.primetime.actions.*;
import com.borland.primetime.node.*;
import com.borland.jbuilder.*;
import com.borland.primetime.ide.*;
//Java
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.tree.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
//JBuilder OT
import com.dafreels.opentools.*;
import com.dafreels.opentools.actions.*;
import com.dafreels.opentools.actions.ui.*;
import com.dafreels.opentools.properties.*;
//Perforce VCS
import com.dafreels.vcs.command.*;
import com.dafreels.vcs.util.ExtensionRegistry;
import com.dafreels.vcs.util.ActionImages;
import java.io.File;
/**
* 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("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("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("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("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;
}
}
}