/* Copyright 2004-2014 Jim Voris
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.qumasoft.guitools.qwin;
import com.qumasoft.guitools.qwin.operation.OperationBaseClass;
import com.qumasoft.guitools.qwin.operation.OperationBreakLock;
import com.qumasoft.guitools.qwin.operation.OperationCheckInArchive;
import com.qumasoft.guitools.qwin.operation.OperationCheckOutArchive;
import com.qumasoft.guitools.qwin.operation.OperationCompareRevisions;
import com.qumasoft.guitools.qwin.operation.OperationCreateArchive;
import com.qumasoft.guitools.qwin.operation.OperationDeleteArchive;
import com.qumasoft.guitools.qwin.operation.OperationGet;
import com.qumasoft.guitools.qwin.operation.OperationLabelArchive;
import com.qumasoft.guitools.qwin.operation.OperationLockArchive;
import com.qumasoft.guitools.qwin.operation.OperationMergeFile;
import com.qumasoft.guitools.qwin.operation.OperationRenameFile;
import com.qumasoft.guitools.qwin.operation.OperationResolveConflictFromParentBranchForTranslucentBranch;
import com.qumasoft.guitools.qwin.operation.OperationSetArchiveAttributes;
import com.qumasoft.guitools.qwin.operation.OperationSetCommentPrefix;
import com.qumasoft.guitools.qwin.operation.OperationSetModuleDescription;
import com.qumasoft.guitools.qwin.operation.OperationSetRevisionDescription;
import com.qumasoft.guitools.qwin.operation.OperationShowInContainingDirectory;
import com.qumasoft.guitools.qwin.operation.OperationUnDeleteArchive;
import com.qumasoft.guitools.qwin.operation.OperationUnLabelArchive;
import com.qumasoft.guitools.qwin.operation.OperationUndoCheckOut;
import com.qumasoft.guitools.qwin.operation.OperationView;
import com.qumasoft.guitools.qwin.operation.OperationViewRevision;
import com.qumasoft.guitools.qwin.operation.OperationVisualCompare;
import com.qumasoft.guitools.qwin.operation.OperationVisualMerge;
import com.qumasoft.qvcslib.AbstractProjectProperties;
import com.qumasoft.qvcslib.DirectoryManagerInterface;
import com.qumasoft.qvcslib.MergedInfoInterface;
import com.qumasoft.qvcslib.QVCSConstants;
import com.qumasoft.qvcslib.RemoteViewProperties;
import com.qumasoft.qvcslib.Utility;
import com.qumasoft.qvcslib.WorkFile;
import com.qumasoft.qvcslib.WorkfileDigestManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.MenuElement;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
/**
* The Right file pane.
*
* @author Jim Voris
*/
public final class RightFilePane extends javax.swing.JPanel implements javax.swing.event.ChangeListener {
private static final long serialVersionUID = 5492608637891716573L;
// Create our logger object
private static final Logger LOGGER = Logger.getLogger("com.qumasoft.guitools.qwin");
private final ActionGetRevision actionGetRevision = new ActionGetRevision("Get...");
private final ActionCheckOutRevision actionCheckOutRevision = new ActionCheckOutRevision("Check Out...");
private final ActionLockArchiveFile actionLockArchiveFile = new ActionLockArchiveFile("Lock...");
private final ActionCheckIn actionCheckIn = new ActionCheckIn("Check In...");
private final ActionUndoCheckOut actionUndoCheckOut = new ActionUndoCheckOut("Undo Check Out...");
private final ActionBreakLock actionBreakLock = new ActionBreakLock("Break Lock");
private final ActionLabel actionLabel = new ActionLabel("Label...");
private final ActionRemoveLabel actionRemoveLabel = new ActionRemoveLabel("Remove Label...");
private final ActionSetAttributes actionSetAttributes = new ActionSetAttributes("Set Attributes...");
private final ActionChangeCommentPrefix actionChangeCommentPrefix = new ActionChangeCommentPrefix("Change Comment Prefix...");
private final ActionChangeFileDescription actionChangeFileDescription = new ActionChangeFileDescription("Change File Description...");
private final ActionChangeRevDescription actionChangeRevDescription = new ActionChangeRevDescription("Change Revision Description...");
private final ActionRenameFile actionRenameFile = new ActionRenameFile("Rename...");
private final ActionDeleteArchive actionDeleteArchive = new ActionDeleteArchive("Delete...");
private final ActionUnDeleteArchive actionUnDeleteArchive = new ActionUnDeleteArchive("UnDelete...");
private final ActionCompare actionCompare = new ActionCompare("Compare");
private final ActionCompareRevisions actionCompareRevisions = new ActionCompareRevisions("Compare Revisions...");
private final ActionMergeFile actionMergeFile = new ActionMergeFile("Merge File...");
private final ActionVisualMerge actionVisualMerge = new ActionVisualMerge("Visual Merge...");
private final ActionResolveConflictFromParentBranch actionResolveConflictFromParentBranch = new ActionResolveConflictFromParentBranch("Resolve conflict from parent branch...");
private final ActionShowInContainingDir actionShowInContainingDir = new ActionShowInContainingDir("Show in Containing Directory");
private final ActionView actionView = new ActionView("View Workfile");
private final ActionViewRevision actionViewRevision = new ActionViewRevision("View Revision...");
private final ActionRemoveUtilityAssociation actionRemoveUtilityAssociation = new ActionRemoveUtilityAssociation("Remove Utility Association");
private final ActionAddArchive actionAddArchive = new ActionAddArchive("Add...");
private final ActionDeleteWorkFile actionDeleteWorkFile = new ActionDeleteWorkFile("Delete Workfile...");
private final ActionWorkfileReadOnly actionWorkfileReadOnly = new ActionWorkfileReadOnly("Make workfile read-only");
private final ActionWorkfileReadWrite actionWorkfileReadWrite = new ActionWorkfileReadWrite("Make workfile read-write");
// Where we keep our table model.
private AbstractFileTableModel tableModel = null;
private int focusIndex = -1;
private final ImageIcon[] sortOrderIcons = {
new ImageIcon(ClassLoader.getSystemResource("images/ascending.png"), "Ascending"),
new ImageIcon(ClassLoader.getSystemResource("images/decending.png"), "Decending")
};
private boolean fileGroupAdjustmentsInProgressFlag = false;
private DataFlavor dropDataFlavor;
private static final Color OVERLAP_BACKGROUND_COLOR = new Color(243, 255, 15);
/**
* Creates new form RightFilePane.
*/
@SuppressWarnings("LeakingThisInConstructor")
public RightFilePane() {
initComponents();
// Add the popup menu actions.
addPopupMenuItems();
// Don't let users drag columns around.
fileTable.getTableHeader().setReorderingAllowed(false);
// Register as a listener of the main frame so we'll know when
// the user changes directories.
QWinFrame.getQWinFrame().addChangeListener(this);
fileTable.setDefaultRenderer(javax.swing.JLabel.class, new CellRenderer());
// Set the JTable to the main frame so other's can easily find it.
QWinFrame.getQWinFrame().setFileTable(fileTable);
// Set the right file pane on the main frame so others can easily find it.
QWinFrame.getQWinFrame().setRightFilePane(this);
// Set up a column listener.
tableModel.addMouseListenerToHeaderInTable(fileTable);
// Set up a different renderer for the column headers.
fileTable.getTableHeader().setDefaultRenderer(new HeaderRenderer(fileTable.getTableHeader().getDefaultRenderer()));
// Set up a selection listener
initSelectionListener();
// Set up drag n drop
initDragAndDrop();
// Init the font
setFontSize(QWinFrame.getQWinFrame().getFontSize());
}
/**
* Called by Swing on a state change.
*
* @param e what changed.
*/
@Override
public void stateChanged(ChangeEvent e) {
setDirectoryManagers(QWinFrame.getQWinFrame().getCurrentDirectoryManagers());
setWorkfileLocationValue(QWinFrame.getQWinFrame().getUserWorkfileDirectory());
}
/**
* Set the workfile location value that gets displayed at the top of the pane.
*
* @param workfileLocation the workfile location.
*/
public void setWorkfileLocationValue(String workfileLocation) {
workfileLocationValue.setText(" " + workfileLocation);
}
/**
* Select the next row that has a workfile that begins with the given character. If no row begins with that character, then don't do anything.
*
* @param keyChar the keyboard character to match.
*/
private void selectMatchingRow(char keyChar) {
char uppercaseKey = Character.toUpperCase(keyChar);
int rowCount = getModel().getRowCount();
int focusIdx = getFocusIndex();
int startingIndex;
if (focusIdx >= 0) {
startingIndex = (focusIdx + 1) % rowCount;
} else {
startingIndex = 0;
}
try {
for (int index = startingIndex, counter = 0; counter < rowCount; index = ++index % rowCount, counter++) {
MergedInfoInterface mergedInfo = getModel().getMergedInfo(index);
String shortWorkfileName = mergedInfo.getShortWorkfileName();
String upperCaseWorkfileName = shortWorkfileName.toUpperCase();
if (upperCaseWorkfileName.startsWith(String.valueOf(uppercaseKey))) {
// Select this row.
final int indexToSelect = index;
// Run this on the swing thread.
Runnable swingTask = new Runnable() {
@Override
public void run() {
QWinFrame.getQWinFrame().getFileTable().getSelectionModel().setSelectionInterval(indexToSelect, indexToSelect);
// Now we need to make sure the file is actually visible...
JTable jTable = QWinFrame.getQWinFrame().getFileTable();
Rectangle visibleRectangle = jTable.getVisibleRect();
Rectangle selectedRectangle = jTable.getCellRect(indexToSelect, 0, true);
// Test to see if the selected file is visible.
if ((selectedRectangle.y > (visibleRectangle.y + visibleRectangle.height))
|| (selectedRectangle.y < visibleRectangle.y)) {
int centerY = visibleRectangle.y + visibleRectangle.height / 2;
if (centerY < selectedRectangle.y) {
// Need to scroll up
selectedRectangle.y = selectedRectangle.y - visibleRectangle.y + centerY;
} else {
// Need to scroll down
selectedRectangle.y = selectedRectangle.y + visibleRectangle.y - centerY;
}
jTable.scrollRectToVisible(selectedRectangle);
}
}
};
SwingUtilities.invokeLater(swingTask);
break;
}
}
} catch (ArrayIndexOutOfBoundsException e) {
// This could happen if they are on the last row already.
LOGGER.log(Level.INFO, e.getLocalizedMessage());
}
}
private void initSelectionListener() {
ListSelectionModel rowSelectionModel = fileTable.getSelectionModel();
rowSelectionModel.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
// Ignore extra messages that arise from file group adjustments.
if (fileGroupAdjustmentsInProgressFlag) {
return;
}
DefaultStyledDocument emptyDoc = new DefaultStyledDocument();
ListSelectionModel listSelectionModel = (ListSelectionModel) listSelectionEvent.getSource();
AbstractFileTableModel dataModel = (AbstractFileTableModel) fileTable.getModel();
int selectedRowCount = 0;
int fileCount = fileTable.getRowCount();
if (!listSelectionModel.isSelectionEmpty()) {
int[] selectedRows = fileTable.getSelectedRows();
if (selectedRows.length == 1) {
setFocusIndex(selectedRows[0]);
}
selectedRows = getFileGroupAdjustedSelectedRows(selectedRows);
selectedRowCount = selectedRows.length;
MergedInfoInterface mergedInfo = dataModel.getMergedInfo(getFocusIndex());
if ((selectedRows.length > 0) && (mergedInfo != null)) {
FilteredFileTableModel filteredFileTableModel = (FilteredFileTableModel) QWinFrame.getQWinFrame().getRightFilePane().getModel();
FilterCollection filterCollection = filteredFileTableModel.getFilterCollection();
// Update the revision info pane...
updateRevisionInfoPane(mergedInfo);
// Update the label info pane...
updateLabelInfoPane(mergedInfo);
// Update the revision and label info pane.
QWinFrame.getQWinFrame().getRevAndLabelInfoPane().setModel(new RevAndLabelInfoModel(mergedInfo));
} else {
QWinFrame.getQWinFrame().getRevisionInfoPane().setDocument(emptyDoc);
QWinFrame.getQWinFrame().getLabelInfoPane().setDocument(emptyDoc);
QWinFrame.getQWinFrame().getRevAndLabelInfoPane().setModel(new RevAndLabelInfoModel());
}
} else {
QWinFrame.getQWinFrame().getRevisionInfoPane().setDocument(emptyDoc);
QWinFrame.getQWinFrame().getLabelInfoPane().setDocument(emptyDoc);
QWinFrame.getQWinFrame().getRevAndLabelInfoPane().setModel(new RevAndLabelInfoModel());
}
QWinFrame.getQWinFrame().getStatusBar().setFileCount(fileCount, selectedRowCount);
}
});
}
/**
* Keep track of the index of the row that has the focus.
*
* @param index the index of the row that has focus.
*/
private void setFocusIndex(int index) {
focusIndex = index;
}
/**
* Get the index of the row that has focus.
*
* @return the index of the row that has focus.
*/
public int getFocusIndex() {
return focusIndex;
}
private int[] getFileGroupAdjustedSelectedRows(int[] selectedRows) {
int[] returnSelectedRows = selectedRows;
fileGroupAdjustmentsInProgressFlag = true;
if (FileGroupManager.getInstance().getEnabledFlag()) {
// Only look for file group files to add for the case
// where we have not already selected all the files.
if (selectedRows.length < fileTable.getRowCount()) {
// First, create a set of the current indexes.
Set<Integer> selectedIndexes = new HashSet<>();
for (int i = 0; i < selectedRows.length; i++) {
selectedIndexes.add(new Integer(selectedRows[i]));
}
// Next, put all the files in the table that are in some
// file group into a map that is keyed by the group name and
// the base part of the file name (note that the key must include
// the appended path, since we only group files that are in
// the same directory).
Map<String, List<Integer>> fileGroupMap = new HashMap<>();
AbstractFileTableModel dataModel = (AbstractFileTableModel) fileTable.getModel();
for (int i = 0; i < dataModel.getRowCount(); i++) {
MergedInfoInterface mergedInfo = dataModel.getMergedInfo(i);
String shortWorkfileName = mergedInfo.getShortWorkfileName();
String groupName = FileGroupManager.getInstance().getGroupNameForFile(shortWorkfileName);
if (groupName != null) {
String baseWorkfileName = Utility.stripFileExtension(shortWorkfileName);
baseWorkfileName = baseWorkfileName.toLowerCase();
String key = groupName + mergedInfo.getArchiveDirManager().getAppendedPath() + baseWorkfileName;
List<Integer> existingIndexes = fileGroupMap.get(key);
if (existingIndexes != null) {
existingIndexes.add(new Integer(i));
} else {
existingIndexes = new ArrayList<>();
existingIndexes.add(new Integer(i));
fileGroupMap.put(key, existingIndexes);
}
}
}
// Next, go through all the currently selected files and add
// any files that are part of that same file group.
for (int i = 0; i < selectedRows.length; i++) {
int selectedIndex = selectedRows[i];
MergedInfoInterface mergedInfo = dataModel.getMergedInfo(selectedIndex);
String shortWorkfileName = mergedInfo.getShortWorkfileName();
String groupName = FileGroupManager.getInstance().getGroupNameForFile(shortWorkfileName);
if (groupName != null) {
String baseWorkfileName = Utility.stripFileExtension(shortWorkfileName);
baseWorkfileName = baseWorkfileName.toLowerCase();
String key = groupName + mergedInfo.getArchiveDirManager().getAppendedPath() + baseWorkfileName;
List existingIndexes = fileGroupMap.get(key);
if (existingIndexes != null) {
// Add all the group's indexes to the list that
// should be selected.
for (int j = 0; j < existingIndexes.size(); j++) {
selectedIndexes.add((Integer) existingIndexes.get(j));
}
}
}
}
// We have now collected all the indexes. Make sure they are
// all selected.
if (selectedIndexes.size() > selectedRows.length) {
Iterator<Integer> it = selectedIndexes.iterator();
returnSelectedRows = new int[selectedIndexes.size()];
ListSelectionModel listSelectionModel = fileTable.getSelectionModel();
int k = 0;
while (it.hasNext()) {
Integer indexToAdd = it.next();
int toAdd = indexToAdd.intValue();
returnSelectedRows[k++] = toAdd;
if (!listSelectionModel.isSelectedIndex(toAdd)) {
listSelectionModel.addSelectionInterval(toAdd, toAdd);
}
}
}
}
}
fileGroupAdjustmentsInProgressFlag = false;
return returnSelectedRows;
}
private void updateRevisionInfoPane(MergedInfoInterface workingMergedInfo) {
SimpleAttributeSet attributeSet = new SimpleAttributeSet();
RevisionInfoContent revisionInfoContent = new RevisionInfoContent(workingMergedInfo);
DefaultStyledDocument revisionInfoDoc = new DefaultStyledDocument();
Iterator it = revisionInfoContent.iterator();
while (it.hasNext()) {
try {
revisionInfoDoc.insertString(0, (String) it.next(), attributeSet);
} catch (BadLocationException e) {
LOGGER.log(Level.INFO, e.getLocalizedMessage());
}
}
QWinFrame.getQWinFrame().getRevisionInfoPane().setDocument(revisionInfoDoc);
}
private void updateLabelInfoPane(MergedInfoInterface workingMergedInfo) {
SimpleAttributeSet attributeSet = new SimpleAttributeSet();
LabelInfoContent labelInfoContent = new LabelInfoContent(workingMergedInfo);
DefaultStyledDocument labelInfoDoc = new DefaultStyledDocument();
Iterator it = labelInfoContent.iterator();
while (it.hasNext()) {
try {
labelInfoDoc.insertString(0, (String) it.next(), attributeSet);
} catch (BadLocationException e) {
LOGGER.log(Level.INFO, e.getLocalizedMessage());
}
}
QWinFrame.getQWinFrame().getLabelInfoPane().setDocument(labelInfoDoc);
}
/**
* Add the menu items to the window's File menu. This is <b>not</b> the file context menu, but the 'static' menu at the top of the main window.
*
* @param menu the parent File menu.
*/
void addPopupMenuItems(javax.swing.JMenu menu) {
Font menuFont = QWinFrame.getQWinFrame().getFont(QWinFrame.getQWinFrame().getFontSize() + 1);
// =====================================================================
JMenuItem menuItem = menu.add(actionGetRevision);
menuItem.setFont(menuFont);
menuItem = menu.add(actionCheckOutRevision);
menuItem.setFont(menuFont);
menuItem = menu.add(actionLockArchiveFile);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionCheckIn);
menuItem.setFont(menuFont);
menuItem = menu.add(actionUndoCheckOut);
menuItem.setFont(menuFont);
menuItem = menu.add(actionBreakLock);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionLabel);
menuItem.setFont(menuFont);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0));
menuItem = menu.add(actionRemoveLabel);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionSetAttributes);
menuItem.setFont(menuFont);
menuItem = menu.add(actionChangeCommentPrefix);
menuItem.setFont(menuFont);
menuItem = menu.add(actionChangeFileDescription);
menuItem.setFont(menuFont);
menuItem = menu.add(actionChangeRevDescription);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionRenameFile);
menuItem.setFont(menuFont);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
menuItem = menu.add(actionDeleteArchive);
menuItem.setFont(menuFont);
menuItem = menu.add(actionUnDeleteArchive);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionCompare);
menuItem.setFont(menuFont);
menuItem = menu.add(actionCompareRevisions);
menuItem.setFont(menuFont);
menuItem = menu.add(actionMergeFile);
menuItem.setFont(menuFont);
menuItem = menu.add(actionVisualMerge);
menuItem.setFont(menuFont);
menuItem = menu.add(actionResolveConflictFromParentBranch);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionShowInContainingDir);
menuItem.setFont(menuFont);
menuItem = menu.add(actionView);
menuItem.setFont(menuFont);
menuItem = menu.add(actionViewRevision);
menuItem.setFont(menuFont);
menuItem = menu.add(actionRemoveUtilityAssociation);
menuItem.setFont(menuFont);
// =====================================================================
menu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = menu.add(actionAddArchive);
menuItem.setFont(menuFont);
menuItem = menu.add(actionDeleteWorkFile);
menuItem.setFont(menuFont);
menuItem = menu.add(actionWorkfileReadOnly);
menuItem.setFont(menuFont);
menuItem = menu.add(actionWorkfileReadWrite);
menuItem.setFont(menuFont);
}
private void addPopupMenuItems() {
Font menuFont = QWinFrame.getQWinFrame().getFont(QWinFrame.getQWinFrame().getFontSize() + 1);
// =====================================================================
JMenuItem menuItem = filePopupMenu.add(actionGetRevision);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionCheckOutRevision);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionLockArchiveFile);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionCheckIn);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionUndoCheckOut);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionBreakLock);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionLabel);
menuItem.setFont(menuFont);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0));
menuItem = filePopupMenu.add(actionRemoveLabel);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionSetAttributes);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionChangeCommentPrefix);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionChangeFileDescription);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionChangeRevDescription);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionRenameFile);
menuItem.setFont(menuFont);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
menuItem = filePopupMenu.add(actionDeleteArchive);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionUnDeleteArchive);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionCompare);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionCompareRevisions);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionMergeFile);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionVisualMerge);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionResolveConflictFromParentBranch);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionShowInContainingDir);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionView);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionViewRevision);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionRemoveUtilityAssociation);
menuItem.setFont(menuFont);
// =====================================================================
filePopupMenu.add(new javax.swing.JSeparator());
// =====================================================================
menuItem = filePopupMenu.add(actionAddArchive);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionDeleteWorkFile);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionWorkfileReadOnly);
menuItem.setFont(menuFont);
menuItem = filePopupMenu.add(actionWorkfileReadWrite);
menuItem.setFont(menuFont);
}
/**
* This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the FormEditor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
filePopupMenu = new javax.swing.JPopupMenu();
scrollPane = new javax.swing.JScrollPane();
fileTable = new javax.swing.JTable();
workfileLocationPanel = new javax.swing.JPanel();
workfileLocationLabel = new javax.swing.JLabel();
workfileLocationValue = new javax.swing.JLabel();
filePopupMenu.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
setLayout(new java.awt.BorderLayout());
fileTable.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N
fileTable.setModel(tableModel = new FilteredFileTableModel());
fileTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
fileTable.setDoubleBuffered(true);
fileTable.setDragEnabled(true);
fileTable.setShowHorizontalLines(false);
fileTable.setShowVerticalLines(false);
fileTable.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
fileTableKeyPressed(evt);
}
});
fileTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
fileTableMouseReleased(evt);
}
});
scrollPane.setViewportView(fileTable);
add(scrollPane, java.awt.BorderLayout.CENTER);
workfileLocationPanel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
workfileLocationPanel.setLayout(new javax.swing.BoxLayout(workfileLocationPanel, javax.swing.BoxLayout.Y_AXIS));
workfileLocationLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
workfileLocationLabel.setText(" Workfile Location:");
workfileLocationLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
workfileLocationPanel.add(workfileLocationLabel);
workfileLocationValue.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
workfileLocationValue.setText(" ");
workfileLocationValue.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
workfileLocationPanel.add(workfileLocationValue);
add(workfileLocationPanel, java.awt.BorderLayout.NORTH);
}// </editor-fold>//GEN-END:initComponents
private void fileTableKeyPressed(java.awt.event.KeyEvent evt)//GEN-FIRST:event_fileTableKeyPressed
{//GEN-HEADEREND:event_fileTableKeyPressed
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
processMouseDoubleClickEvent();
evt.consume();
}
if ((evt.getKeyCode() >= KeyEvent.VK_0) && (evt.getKeyCode() <= KeyEvent.VK_Z)) {
selectMatchingRow(evt.getKeyChar());
}
}//GEN-LAST:event_fileTableKeyPressed
private void fileTableMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_fileTableMouseReleased
{//GEN-HEADEREND:event_fileTableMouseReleased
// Add your handling code here:
if (evt.isPopupTrigger() || ((evt.getButton() == MouseEvent.BUTTON3) && (0 != (evt.getModifiers() & MouseEvent.MOUSE_RELEASED)))) {
int row = fileTable.rowAtPoint(new Point(evt.getX(), evt.getY()));
if (!fileTable.isRowSelected(row)) {
fileTable.setRowSelectionInterval(row, row);
}
enableMenuItems();
filePopupMenu.show(fileTable, evt.getX(), evt.getY());
} else if (2 == evt.getClickCount()) {
// The user double clicked.
processMouseDoubleClickEvent();
}
}//GEN-LAST:event_fileTableMouseReleased
void enableMenuItems() {
// Figure out what to enable/disable on the popup menu...
boolean cemeteryIncludedFlag = false;
boolean branchArchiveDirectoryIncludedFlag = false;
List mergedInfoArray = getSelectedFiles();
Iterator it = mergedInfoArray.iterator();
if (mergedInfoArray.size() > 0) {
enableAllPopUpOperations();
FilteredFileTableModel filteredFileTableModel = (FilteredFileTableModel) QWinFrame.getQWinFrame().getRightFilePane().getModel();
int mergeFromParentCount = 0;
while (it.hasNext()) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) it.next();
if (mergedInfo.getIsOverlap() && (mergedInfo.getStatusIndex() == MergedInfoInterface.CURRENT_STATUS_INDEX)) {
mergeFromParentCount++;
}
if (mergedInfo.getArchiveInfo() == null) {
disableArchivePopUpOperations();
} else {
disableArchiveExistsOperations();
}
if (mergedInfo.getWorkfileInfo() == null) {
disableWorkfilePopUpOperations();
}
if (mergedInfo.getLockCount() > 0) {
disableFileIsLockedOperations();
}
// Disable delete if any selected files are in the cemetery.
String appendedPath = mergedInfo.getArchiveDirManager().getAppendedPath();
if (0 == appendedPath.compareTo(QVCSConstants.QVCS_CEMETERY_DIRECTORY)) {
actionDeleteArchive.setEnabled(false);
cemeteryIncludedFlag = true;
}
if (0 == appendedPath.compareTo(QVCSConstants.QVCS_BRANCH_ARCHIVES_DIRECTORY)) {
actionDeleteArchive.setEnabled(false);
branchArchiveDirectoryIncludedFlag = true;
}
}
if (mergedInfoArray.size() != 1) {
disableSingleFileOperations();
} else {
checkRemoveFileAssociationOperation((MergedInfoInterface) mergedInfoArray.get(0));
}
// Enable the undelete operation only when the cemetery is selected
// and they have selected just one file...
if (mergedInfoArray.size() == 1) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) mergedInfoArray.get(0);
String appendedPath = mergedInfo.getArchiveDirManager().getAppendedPath();
if ((0 == appendedPath.compareTo(QVCSConstants.QVCS_CEMETERY_DIRECTORY))
|| (0 == appendedPath.compareTo(QVCSConstants.QVCS_BRANCH_ARCHIVES_DIRECTORY))) {
disableAllPopUpOperations();
actionUnDeleteArchive.setEnabled(true);
actionCompareRevisions.setEnabled(true);
}
} else {
// Multiple files have been selected. If any of the selected files are in the cemetery or
// branch archive directory, then don't allow anything.
if (cemeteryIncludedFlag || branchArchiveDirectoryIncludedFlag) {
disableAllPopUpOperations();
}
}
if (mergeFromParentCount == mergedInfoArray.size()) {
enableMergeFromParentOperation();
} else {
disableMergeFromParentOperation();
}
} else {
disableAllPopUpOperations();
}
}
private void processMouseDoubleClickEvent() {
// We get here by typing the enter key, or by double clicking on the
// file.
actionView.actionPerformed(null);
}
private void setDirectoryManagers(DirectoryManagerInterface[] managers) {
AbstractFileTableModel model = (AbstractFileTableModel) fileTable.getModel();
model.setDirectoryManagers(managers, false, false);
}
private void enableAllPopUpOperations() {
actionGetRevision.setEnabled(true);
actionCheckOutRevision.setEnabled(true);
actionLockArchiveFile.setEnabled(true);
actionCheckIn.setEnabled(true);
actionUndoCheckOut.setEnabled(true);
actionBreakLock.setEnabled(true);
actionLabel.setEnabled(true);
actionRemoveLabel.setEnabled(true);
actionSetAttributes.setEnabled(true);
actionChangeCommentPrefix.setEnabled(true);
actionChangeFileDescription.setEnabled(true);
actionChangeRevDescription.setEnabled(true);
actionRenameFile.setEnabled(true);
actionDeleteArchive.setEnabled(true);
actionUnDeleteArchive.setEnabled(false);
actionCompare.setEnabled(true);
actionCompareRevisions.setEnabled(true);
actionMergeFile.setEnabled(true);
actionVisualMerge.setEnabled(true);
actionResolveConflictFromParentBranch.setEnabled(true);
actionShowInContainingDir.setEnabled(true);
actionView.setEnabled(true);
actionViewRevision.setEnabled(true);
actionRemoveUtilityAssociation.setEnabled(true);
actionAddArchive.setEnabled(true);
actionDeleteWorkFile.setEnabled(true);
actionWorkfileReadOnly.setEnabled(true);
actionWorkfileReadWrite.setEnabled(true);
}
private void disableAllPopUpOperations() {
actionGetRevision.setEnabled(false);
actionCheckOutRevision.setEnabled(false);
actionLockArchiveFile.setEnabled(false);
actionCheckIn.setEnabled(false);
actionUndoCheckOut.setEnabled(false);
actionBreakLock.setEnabled(false);
actionLabel.setEnabled(false);
actionRemoveLabel.setEnabled(false);
actionSetAttributes.setEnabled(false);
actionChangeCommentPrefix.setEnabled(false);
actionChangeFileDescription.setEnabled(false);
actionChangeRevDescription.setEnabled(false);
actionRenameFile.setEnabled(false);
actionDeleteArchive.setEnabled(false);
actionUnDeleteArchive.setEnabled(false);
actionCompare.setEnabled(false);
actionCompareRevisions.setEnabled(false);
actionMergeFile.setEnabled(false);
actionVisualMerge.setEnabled(false);
actionResolveConflictFromParentBranch.setEnabled(false);
actionShowInContainingDir.setEnabled(false);
actionView.setEnabled(false);
actionViewRevision.setEnabled(false);
actionRemoveUtilityAssociation.setEnabled(false);
actionAddArchive.setEnabled(false);
actionDeleteWorkFile.setEnabled(false);
actionWorkfileReadOnly.setEnabled(false);
actionWorkfileReadWrite.setEnabled(false);
}
private void disableArchivePopUpOperations() {
actionGetRevision.setEnabled(false);
actionCheckOutRevision.setEnabled(false);
actionLockArchiveFile.setEnabled(false);
actionCheckIn.setEnabled(false);
actionUndoCheckOut.setEnabled(false);
actionBreakLock.setEnabled(false);
actionLabel.setEnabled(false);
actionRemoveLabel.setEnabled(false);
actionSetAttributes.setEnabled(false);
actionChangeCommentPrefix.setEnabled(false);
actionChangeFileDescription.setEnabled(false);
actionChangeRevDescription.setEnabled(false);
actionDeleteArchive.setEnabled(false);
actionUnDeleteArchive.setEnabled(false);
actionCompare.setEnabled(false);
actionCompareRevisions.setEnabled(false);
actionMergeFile.setEnabled(false);
actionVisualMerge.setEnabled(false);
actionResolveConflictFromParentBranch.setEnabled(false);
actionViewRevision.setEnabled(false);
}
private void disableArchiveExistsOperations() {
actionAddArchive.setEnabled(false);
}
private void disableWorkfilePopUpOperations() {
actionCompare.setEnabled(false);
actionView.setEnabled(false);
actionAddArchive.setEnabled(false);
actionDeleteWorkFile.setEnabled(false);
actionWorkfileReadOnly.setEnabled(false);
actionWorkfileReadWrite.setEnabled(false);
}
private void disableSingleFileOperations() {
actionChangeRevDescription.setEnabled(false);
actionRenameFile.setEnabled(false);
actionShowInContainingDir.setEnabled(false);
actionView.setEnabled(false);
actionViewRevision.setEnabled(false);
actionRemoveUtilityAssociation.setEnabled(false);
}
private void disableFileIsLockedOperations() {
actionRenameFile.setEnabled(false);
}
private void enableMergeFromParentOperation() {
actionResolveConflictFromParentBranch.setEnabled(true);
}
private void disableMergeFromParentOperation() {
actionResolveConflictFromParentBranch.setEnabled(false);
}
private void checkRemoveFileAssociationOperation(MergedInfoInterface mergedInfo) {
String shortWorkfileName = mergedInfo.getShortWorkfileName();
if (!ViewUtilityManager.getInstance().getHasAssociatedUtility(shortWorkfileName)) {
actionRemoveUtilityAssociation.setEnabled(false);
}
}
private List getSelectedFiles() {
int[] selectedRows = fileTable.getSelectedRows();
AbstractFileTableModel dataModel = (AbstractFileTableModel) fileTable.getModel();
List<MergedInfoInterface> mergedInfoArray = new ArrayList<>();
// Save the information from the selected files. We do this before
// we do any work, since the doing of work will change the selection
// status of the files.
for (int i = 0; i < selectedRows.length; i++) {
// Save the names of the archives we'll work on.
int selectedRowIndex = selectedRows[i];
MergedInfoInterface mergedInfo = dataModel.getMergedInfo(selectedRowIndex);
if (mergedInfo != null) {
mergedInfoArray.add(mergedInfo);
}
}
return mergedInfoArray;
}
/**
* Get the table data model.
*
* @return the abstract file table model.
*/
public AbstractFileTableModel getModel() {
return tableModel;
}
/**
* Initialize drag and drop.
*/
private void initDragAndDrop() {
fileTable.setDragEnabled(true);
fileTable.setTransferHandler(new MyTransferHandler());
}
/**
* Get the type of drop data.
*
* @return the 'flavor' of drop data.
*/
public DataFlavor getDropDataFlavor() {
return dropDataFlavor;
}
/**
* Set the font size.
*
* @param fontSize the font size.
*/
public void setFontSize(int fontSize) {
fileTable.setFont(QWinFrame.getQWinFrame().getFont(fontSize));
workfileLocationLabel.setFont(QWinFrame.getQWinFrame().getFont(fontSize + 1));
workfileLocationValue.setFont(QWinFrame.getQWinFrame().getFont(fontSize + 1));
setMenuFontSize(fontSize + 1);
}
private void setMenuFontSize(int fontSize) {
Font font = QWinFrame.getQWinFrame().getFont(fontSize);
MenuElement menuElements[] = filePopupMenu.getSubElements();
for (MenuElement menuElement : menuElements) {
menuElement.getComponent().setFont(font);
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPopupMenu filePopupMenu;
private javax.swing.JTable fileTable;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JLabel workfileLocationLabel;
private javax.swing.JPanel workfileLocationPanel;
private javax.swing.JLabel workfileLocationValue;
// End of variables declaration//GEN-END:variables
class CellRenderer extends javax.swing.table.DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JLabel inputLabel = (JLabel) fileTable.getModel().getValueAt(row, column);
FileTableModel fileTableModel = (FileTableModel) fileTable.getModel();
MergedInfoInterface mergedInfo = fileTableModel.getMergedInfo(row);
// Set the column alignment.
switch (column) {
case AbstractFileTableModel.FILE_STATUS_COLUMN_INDEX:
case AbstractFileTableModel.LOCKEDBY_COLUMN_INDEX:
case AbstractFileTableModel.LASTEDITBY_COLUMN_INDEX: {
setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
break;
}
case AbstractFileTableModel.FILESIZE_COLUMN_INDEX: {
setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
break;
}
case AbstractFileTableModel.FILENAME_COLUMN_INDEX:
case AbstractFileTableModel.APPENDED_PATH_INDEX:
case AbstractFileTableModel.LASTCHECKIN_COLUMN_INDEX:
case AbstractFileTableModel.WORKFILEIN_COLUMN_INDEX:
default: {
setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
break;
}
}
if (isSelected) {
super.setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
if (row == getFocusIndex()) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
setBorder(noFocusBorder);
}
} else {
if ((mergedInfo != null) && mergedInfo.getIsOverlap()) {
super.setBackground(OVERLAP_BACKGROUND_COLOR);
} else {
super.setBackground(table.getBackground());
}
super.setForeground(table.getForeground());
setBorder(noFocusBorder);
}
if ((mergedInfo != null) && mergedInfo.getIsOverlap()) {
setToolTipText(" Conflict with Parent");
} else {
setToolTipText(null);
}
setFont(table.getFont());
setText(inputLabel.getText());
if (column == 0 && inputLabel.getIcon() != null) {
setIcon(inputLabel.getIcon());
} else {
setIcon(null);
}
return this;
}
}
class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
private TableCellRenderer m_defaultRenderer = null;
HeaderRenderer(TableCellRenderer defaultRenderer) {
m_defaultRenderer = defaultRenderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer component = (DefaultTableCellRenderer) m_defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
AbstractFileTableModel fileTableModel = (AbstractFileTableModel) fileTable.getModel();
if (fileTableModel.getSortColumnInteger() == column) {
if (fileTableModel.getAscendingFlag()) {
component.setIcon(sortOrderIcons[0]);
} else {
component.setIcon(sortOrderIcons[1]);
}
} else {
component.setIcon(null);
}
component.setFont(table.getFont());
return component;
}
}
class ActionGetRevision extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionGetRevision(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass getOperation = new OperationGet(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties(), true);
getOperation.executeOperation();
}
}
class ActionCheckOutRevision extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionCheckOutRevision(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass checkOutOperation = new OperationCheckOutArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties(), true);
checkOutOperation.executeOperation();
}
}
class ActionLockArchiveFile extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionLockArchiveFile(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass lockOperation = new OperationLockArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties(), true);
lockOperation.executeOperation();
}
}
class ActionCheckIn extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionCheckIn(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass checkinOperation = new OperationCheckInArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
checkinOperation.executeOperation();
}
}
class ActionUndoCheckOut extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionUndoCheckOut(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass undoCheckOutOperation = new OperationUndoCheckOut(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties(), true);
undoCheckOutOperation.executeOperation();
}
}
class ActionBreakLock extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionBreakLock(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO
// This is where I need to put the break lock dialog, and only after the
// dialog is dismissed with an OK so I actually perform the operation.
OperationBaseClass breakLockOperation = new OperationBreakLock(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
breakLockOperation.executeOperation();
}
}
class ActionLabel extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionLabel(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass labelOperation = new OperationLabelArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
labelOperation.executeOperation();
}
}
class ActionRemoveLabel extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionRemoveLabel(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass unLabelOperation = new OperationUnLabelArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
unLabelOperation.executeOperation();
}
}
class ActionSetAttributes extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionSetAttributes(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass setAttributesOperation = new OperationSetArchiveAttributes(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
setAttributesOperation.executeOperation();
}
}
class ActionChangeCommentPrefix extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionChangeCommentPrefix(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass setCommentPrefix = new OperationSetCommentPrefix(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
setCommentPrefix.executeOperation();
}
}
class ActionChangeFileDescription extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionChangeFileDescription(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass setModuleDescription = new OperationSetModuleDescription(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
setModuleDescription.executeOperation();
}
}
class ActionChangeRevDescription extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionChangeRevDescription(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass setRevisionDescription = new OperationSetRevisionDescription(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
setRevisionDescription.executeOperation();
}
}
class ActionRenameFile extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionRenameFile(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass renameFileOperation = new OperationRenameFile(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
renameFileOperation.executeOperation();
}
}
class ActionDeleteArchive extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionDeleteArchive(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass deleteOperation = new OperationDeleteArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
deleteOperation.executeOperation();
}
}
class ActionUnDeleteArchive extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionUnDeleteArchive(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass unDeleteOperation = new OperationUnDeleteArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
unDeleteOperation.executeOperation();
}
}
class ActionCompare extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionCompare(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass visualCompareOperation = new OperationVisualCompare(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
visualCompareOperation.executeOperation();
}
}
class ActionCompareRevisions extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionCompareRevisions(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass compareRevisionsOperation = new OperationCompareRevisions(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
compareRevisionsOperation.executeOperation();
}
}
class ActionMergeFile extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionMergeFile(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass mergeFileOperation = new OperationMergeFile(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
mergeFileOperation.executeOperation();
}
}
class ActionVisualMerge extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionVisualMerge(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass visualMergeOperation = new OperationVisualMerge(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
visualMergeOperation.executeOperation();
}
}
class ActionResolveConflictFromParentBranch extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionResolveConflictFromParentBranch(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
String serverName = QWinFrame.getQWinFrame().getServerName();
String projectName = QWinFrame.getQWinFrame().getProjectName();
String viewName = QWinFrame.getQWinFrame().getViewName();
ProjectTreeModel projectTreeModel = QWinFrame.getQWinFrame().getTreeModel();
ViewTreeNode projectTreeNode = projectTreeModel.findProjectViewTreeNode(serverName, projectName, viewName);
if (viewName.equals(QVCSConstants.QVCS_TRUNK_VIEW)) {
QWinUtility.logProblem(Level.SEVERE, "Attempt to resolve branch conflict on trunk!");
} else {
AbstractProjectProperties abstractProjectProperties = projectTreeNode.getProjectProperties();
if (abstractProjectProperties instanceof RemoteViewProperties) {
RemoteViewProperties remoteViewProperties = (RemoteViewProperties) abstractProjectProperties;
if (remoteViewProperties.getIsTranslucentBranchFlag()) {
OperationBaseClass resolveConflictFromParentBranchForTranslucentBranch = new OperationResolveConflictFromParentBranchForTranslucentBranch(fileTable,
serverName, projectName, viewName, QWinFrame.getQWinFrame().getUserLocationProperties());
resolveConflictFromParentBranchForTranslucentBranch.executeOperation();
}
}
}
}
}
class ActionShowInContainingDir extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionShowInContainingDir(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass showInContainingDirectoryOperation = new OperationShowInContainingDirectory(fileTable, QWinFrame.getQWinFrame().getServerName(),
QWinFrame.getQWinFrame().getProjectName(), QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
showInContainingDirectoryOperation.executeOperation();
}
}
class ActionView extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionView(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass viewOperation = new OperationView(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
viewOperation.executeOperation();
}
}
class ActionViewRevision extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionViewRevision(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass viewRevisionOperation = new OperationViewRevision(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties());
viewRevisionOperation.executeOperation();
}
}
class ActionRemoveUtilityAssociation extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionRemoveUtilityAssociation(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
// We only do anything if there is just one file selected.
List selectedFiles = getSelectedFiles();
if (selectedFiles.size() == 1) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) selectedFiles.get(0);
String fullWorkfileName = mergedInfo.getFullWorkfileName();
ViewUtilityManager.getInstance().removeUtilityAssociation(fullWorkfileName);
}
}
}
class ActionAddArchive extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionAddArchive(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
OperationBaseClass addOperation = new OperationCreateArchive(fileTable, QWinFrame.getQWinFrame().getServerName(), QWinFrame.getQWinFrame().getProjectName(),
QWinFrame.getQWinFrame().getViewName(), QWinFrame.getQWinFrame().getUserLocationProperties(), true);
addOperation.executeOperation();
}
}
class ActionDeleteWorkFile extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionDeleteWorkFile(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
final List mergedInfoArray = getSelectedFiles();
// Run the update on the Swing thread.
Runnable later = new Runnable() {
@Override
public void run() {
// Let the user know that the client is out of date.
int answer = JOptionPane.showConfirmDialog(QWinFrame.getQWinFrame(), "Delete the selected workfile(s)?", "Delete Selected Workfiles",
JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (answer == JOptionPane.YES_OPTION) {
Iterator it = mergedInfoArray.iterator();
boolean modelChanged = false;
while (it.hasNext()) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) it.next();
if (mergedInfo.getWorkfileInfo().getWorkfile().delete()) {
modelChanged = true;
WorkfileDigestManager.getInstance().removeWorkfileDigest(mergedInfo.getWorkfileInfo());
LOGGER.log(Level.INFO, "Deleted workfile: " + mergedInfo.getWorkfileInfo().getFullWorkfileName());
}
}
if (modelChanged) {
QWinFrame.getQWinFrame().refreshCurrentView();
}
}
}
};
SwingUtilities.invokeLater(later);
}
}
class ActionWorkfileReadOnly extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionWorkfileReadOnly(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
List mergedInfoArray = getSelectedFiles();
Iterator it = mergedInfoArray.iterator();
while (it.hasNext()) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) it.next();
if (mergedInfo.getWorkfileInfo() != null) {
WorkFile workFile = new WorkFile(mergedInfo.getWorkfileInfo().getFullWorkfileName());
workFile.setReadOnly();
}
}
}
}
class ActionWorkfileReadWrite extends AbstractAction {
private static final long serialVersionUID = 1L;
ActionWorkfileReadWrite(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(ActionEvent e) {
List mergedInfoArray = getSelectedFiles();
Iterator it = mergedInfoArray.iterator();
while (it.hasNext()) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) it.next();
if (mergedInfo.getWorkfileInfo() != null) {
WorkFile workFile = new WorkFile(mergedInfo.getWorkfileInfo().getFullWorkfileName());
workFile.setReadWrite();
}
}
}
}
class MyTransferHandler extends TransferHandler {
private static final long serialVersionUID = 1L;
@Override
protected Transferable createTransferable(JComponent c) {
Transferable transferable = null;
java.util.List selectedFiles = getSelectedFiles();
if (selectedFiles.size() == 1) {
MergedInfoInterface mergedInfo = (MergedInfoInterface) selectedFiles.get(0);
String filename = null;
if (mergedInfo.getWorkfileExists()) {
filename = mergedInfo.getWorkfileInfo().getFullWorkfileName();
}
transferable = new MyTransferable(filename, mergedInfo.getProjectName(), mergedInfo.getArchiveDirManager().getViewName(), mergedInfo.getArchiveDirManager().getAppendedPath(),
mergedInfo.getShortWorkfileName());
}
return transferable;
}
@Override
public boolean canImport(JComponent c, DataFlavor[] flavors) {
return false;
}
@Override
public int getSourceActions(JComponent c) {
int action = NONE;
java.util.List selectedFiles = getSelectedFiles();
if (selectedFiles.size() == 1) {
action = COPY_OR_MOVE;
}
return action;
}
@Override
protected void exportDone(JComponent c, Transferable data, int action) {
// Nothing to do here.
}
}
final class MyTransferable implements java.awt.datatransfer.Transferable {
private final DataFlavor[] windowsFlavors = {null, DataFlavor.javaFileListFlavor, DataFlavor.stringFlavor};
private final DataFlavor[] linuxFlavors = {null, DataFlavor.stringFlavor};
private final List<File> fileList = new ArrayList<>();
private String fileName = null;
private File file = null;
private DropTransferData dropTransferData = null;
private boolean windowsFlag = false;
MyTransferable(final String filename, final String projectName, final String viewName, final String appendedPath, final String shortWorkfileName) {
if (filename != null) {
fileList.add(new File(filename));
fileName = filename;
file = new File(fileName);
}
dropTransferData = new DropTransferData(projectName, viewName, appendedPath, shortWorkfileName);
String OSName = System.getProperty("os.name");
if (OSName.startsWith("Windows")) {
windowsFlag = true;
}
try {
dropDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=com.qumasoft.guitools.qwin.DropTransferData");
windowsFlavors[0] = dropDataFlavor;
linuxFlavors[0] = dropDataFlavor;
} catch (ClassNotFoundException e) {
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
}
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (!isDataFlavorSupported(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
LOGGER.log(Level.INFO, "DataFlavor:" + flavor.getHumanPresentableName());
if (flavor.equals(DataFlavor.javaFileListFlavor)) {
if (file != null) {
return fileList;
} else {
return null;
}
} else if (flavor.equals(DataFlavor.stringFlavor)) {
// I've got to open the workfile, read its contents into
// a String object, and return that String object.
if (file != null && file.exists()) {
FileInputStream fileInputStream;
try {
fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
fileInputStream.read(buffer);
String returnValue = new String(buffer);
fileInputStream.close();
return returnValue;
} catch (FileNotFoundException e) {
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
return "Caught exception: " + e.getLocalizedMessage();
} catch (IOException e) {
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
return "Caught exception: " + e.getLocalizedMessage();
}
} else {
return null;
}
} else if (flavor.equals(dropDataFlavor)) {
return dropTransferData;
} else {
return null;
}
}
@Override
public DataFlavor[] getTransferDataFlavors() {
if (windowsFlag) {
return windowsFlavors;
} else {
return linuxFlavors;
}
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
if (flavor.equals(DataFlavor.javaFileListFlavor)) {
return true;
} else if (flavor.equals(DataFlavor.stringFlavor)) {
return true;
} else {
return flavor.equals(dropDataFlavor);
}
}
}
}