diff --git a/platform/icons/src/vcs/arrow_left.png b/platform/icons/src/vcs/arrow_left.png new file mode 100644 index 000000000000..07020202da2a Binary files /dev/null and b/platform/icons/src/vcs/arrow_left.png differ diff --git a/platform/icons/src/vcs/arrow_right.png b/platform/icons/src/vcs/arrow_right.png new file mode 100644 index 000000000000..d9d57f7474d3 Binary files /dev/null and b/platform/icons/src/vcs/arrow_right.png differ diff --git a/platform/icons/src/vcs/merge.png b/platform/icons/src/vcs/merge.png new file mode 100644 index 000000000000..d80ef407f806 Binary files /dev/null and b/platform/icons/src/vcs/merge.png differ diff --git a/platform/icons/src/vcs/remove.png b/platform/icons/src/vcs/remove.png new file mode 100644 index 000000000000..c5fc0f8d54f7 Binary files /dev/null and b/platform/icons/src/vcs/remove.png differ diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java index 09f59251b3aa..da8079af733c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffElement.java @@ -19,6 +19,12 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.sql.Date; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import static com.intellij.openapi.diff.impl.dir.DirDiffOperation.*; + /** * @author Konstantin Bulenkov */ @@ -29,6 +35,7 @@ public class DirDiffElement { private final VirtualFile myTarget; private final long myTargetLength; private final String myName; + private DirDiffOperation myOperation; private DirDiffElement(@Nullable VirtualFile source, @Nullable VirtualFile target, ElementType type, String name) { myType = type; @@ -37,14 +44,28 @@ public class DirDiffElement { myTarget = target; myTargetLength = target == null || target.isDirectory() ? -1 : target.getLength(); myName = name; + if (isSource()) { + myOperation = COPY_TO; + } + else if (isTarget()) { + myOperation = DirDiffOperation.COPY_FROM; + } + else if (type == ElementType.CHANGED) { + assert source != null; + myOperation = source.getFileType().isBinary() ? NONE : DirDiffOperation.MERGE; + } } public String getSourceModificationDate() { - return null; + return mySource == null ? "" : getLastModification(mySource); } public String getTargetModificationDate() { - return null; + return myTarget == null ? "" : getLastModification(myTarget); + } + + private static String getLastModification(VirtualFile file) { + return SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(new Date(file.getTimeStamp())); } public static DirDiffElement createChange(@NotNull VirtualFile source, @NotNull VirtualFile target) { @@ -105,5 +126,28 @@ public class DirDiffElement { return myType == ElementType.SEPARATOR; } + public boolean isSource() { + return myType == ElementType.SOURCE; + } + + public boolean isTarget() { + return myType == ElementType.TARGET; + } + + public DirDiffOperation getOperation() { + return myOperation; + } + + public void setNextOperation() { + final DirDiffOperation o = myOperation; + if (isSource()) { + myOperation = o == COPY_TO ? REMOVE : o == REMOVE ? NONE : COPY_TO; + } else if (isTarget()) { + myOperation = o == COPY_FROM ? REMOVE : o == REMOVE ? NONE : COPY_FROM; + } else { + myOperation = o == MERGE ? COPY_TO : o == COPY_TO ? COPY_FROM : o == COPY_FROM ? NONE : MERGE; + } + } + public static enum ElementType {SOURCE, TARGET, SEPARATOR, CHANGED} } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffOperation.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffOperation.java new file mode 100644 index 000000000000..357166580c6e --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffOperation.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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.intellij.openapi.diff.impl.dir; + +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.ui.EmptyIcon; + +import javax.swing.*; + +/** + * @author Konstantin Bulenkov + */ +public enum DirDiffOperation { + COPY_TO, COPY_FROM, REMOVE, MERGE, NONE; + + public Icon getIcon() { + switch (this) { + case COPY_TO: return IconLoader.getIcon("/vcs/arrow_right.png"); + case COPY_FROM: return IconLoader.getIcon("/vcs/arrow_left.png"); + case REMOVE: return IconLoader.getIcon("/vcs/remove.png"); + case MERGE: return IconLoader.getIcon("/vcs/merge.png"); + case NONE: return EmptyIcon.create(12); + } + return null; + } +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form index 96e9a9e53d1d..354d8a890393 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form @@ -1,7 +1,6 @@
diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java index 8b9b40a029b5..294a0e69766d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java @@ -25,13 +25,17 @@ import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.components.JBLabel; import com.intellij.ui.table.JBTable; +import com.intellij.util.Icons; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -44,6 +48,10 @@ public class DirDiffPanel { private JBTable myTable; private JPanel myComponent; private JSplitPane mySplitPanel; + private TextFieldWithBrowseButton mySourceDirField; + private TextFieldWithBrowseButton myTargetDirField; + private JBLabel myTargetDirLabel; + private JBLabel mySourceDirLabel; private final DirDiffTableModel myModel; private final DirDiffDialog myDialog; private DiffPanel myDiffPanelComponent; @@ -52,6 +60,10 @@ public class DirDiffPanel { public DirDiffPanel(DirDiffTableModel model, DirDiffDialog dirDiffDialog) { myModel = model; myDialog = dirDiffDialog; + mySourceDirField.setText(model.getSourceDir().getPath()); + myTargetDirField.setText(model.getTargetDir().getPath()); + mySourceDirLabel.setIcon(Icons.FOLDER_ICON); + myTargetDirLabel.setIcon(Icons.FOLDER_ICON); myTable.setModel(myModel); final DirDiffTableCellRenderer renderer = new DirDiffTableCellRenderer(myTable); myTable.setDefaultRenderer(Object.class, renderer); @@ -83,7 +95,7 @@ public class DirDiffPanel { } else { clearDiffPanel(); - final VirtualFile file = element.getType() == DirDiffElement.ElementType.SOURCE ? element.getSource() : element.getTarget(); + final VirtualFile file = element.isSource() ? element.getSource() : element.getTarget(); final Document document = FileDocumentManager.getInstance().getDocument(file); myEditor = (EditorEx)EditorFactory.getInstance().createEditor(document, project, file, true); myEditor.getSettings().setFoldingOutlineShown(false); @@ -91,6 +103,7 @@ public class DirDiffPanel { myDiffPanel.revalidate(); } } + myDialog.setTitle(myModel.getTitle()); } }); myTable.addKeyListener(new KeyAdapter() { @@ -118,6 +131,9 @@ public class DirDiffPanel { } } }); + final TableColumn operationColumn = myTable.getColumnModel().getColumn(3); + operationColumn.setMaxWidth(25); + operationColumn.setMinWidth(25); } private void clearDiffPanel() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java index 6ded4a6871ec..2cb81f2ff76e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableCellRenderer.java @@ -15,10 +15,12 @@ */ package com.intellij.openapi.diff.impl.dir; +import com.intellij.openapi.vcs.FileStatus; import com.intellij.ui.table.JBTable; import com.intellij.util.IconUtil; import com.intellij.util.Icons; import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.UIUtil; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -68,14 +70,42 @@ public class DirDiffTableCellRenderer extends DefaultTableCellRenderer { } }; } - final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (c instanceof JLabel && (hasFocus || isSelected)) { - ((JLabel)c).setBorder(noFocusBorder); + if (c instanceof JLabel) { + final JLabel label = (JLabel)c; + if (hasFocus || isSelected) { + label.setBorder(noFocusBorder); + } + + final DirDiffOperation op = element.getOperation(); + if (column == 3) { + label.setIcon(op.getIcon()); + label.setHorizontalAlignment(CENTER); + return label; + } else { + label.setIcon(null); + } + + Color fg = isSelected ? UIUtil.getTableSelectionForeground() : getForegroundColor(op); + label.setForeground(fg); + if (column == 2 || column == 4) { + label.setHorizontalAlignment(CENTER); + } else if (column == 1 || column == 5) { + label.setHorizontalAlignment(RIGHT); + label.setText(label.getText() + " "); + } else { + label.setHorizontalAlignment(LEFT); + label.setText(" " + label.getText()); + } } return c; } + private static Color getForegroundColor(DirDiffOperation op) { + return op == DirDiffOperation.COPY_TO || op == DirDiffOperation.COPY_FROM + ? FileStatus.COLOR_ADDED : FileStatus.COLOR_MODIFIED; + } + private BufferedImage getOrCreate(String path) { final BufferedImage image = cache.get(path); if (image != null) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java index fbf40ec0e2c9..3a35ed77747f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java @@ -30,6 +30,8 @@ import java.util.*; */ public class DirDiffTableModel extends AbstractTableModel { private final Project myProject; + private VirtualFile mySrc; + private VirtualFile myTrg; final List