diff --git a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java index f06fe968c3d1..88a80da4c239 100644 --- a/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java +++ b/platform/platform-api/src/com/intellij/ide/diff/DiffElement.java @@ -25,17 +25,20 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.IOException; +import java.nio.charset.Charset; /** * @author Konstantin Bulenkov */ public abstract class DiffElement { + public static final DiffElement[] EMPTY_ARRAY = new DiffElement[0]; private DiffPanel myDiffPanel; private Editor myEditor; @@ -54,7 +57,7 @@ public abstract class DiffElement { public abstract boolean isContainer(); - public abstract DiffElement[] getChildren(); + public abstract DiffElement[] getChildren() throws IOException; @Nullable public abstract DiffElement findFileByRelativePath(String path); @@ -67,6 +70,10 @@ public abstract class DiffElement { @Nullable public abstract byte[] getContent() throws IOException; + public Charset getCharset() { + return EncodingManager.getInstance().getDefaultCharset(); + } + @Nullable public JComponent getViewComponent(Project project) { disposeViewComponent(); @@ -97,6 +104,8 @@ public abstract class DiffElement { myDiffPanel = DiffManager.getInstance().createDiffPanel(parentWindow, project); myDiffPanel.setRequestFocus(false); myDiffPanel.setDiffRequest(request); + myDiffPanel.setTitle1(getName()); + myDiffPanel.setTitle2(element.getName()); return myDiffPanel.getComponent(); } @@ -126,7 +135,7 @@ public abstract class DiffElement { @Nullable protected DiffContent createDiffContent() { try { - return new SimpleContent(new String(getContent()), getFileType()); + return new SimpleContent(new String(getContent(), getCharset()), getFileType()); } catch (IOException e) {// } @@ -148,4 +157,13 @@ public abstract class DiffElement { myDiffPanel = null; } } + + public String getSeparator() { + return "/"; + } + + @Nullable + public Icon getIcon() { + return null; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java b/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java index ad8c1361a1f1..6a7fc044dfb5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/DirDiffManager.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -28,7 +29,7 @@ public abstract class DirDiffManager { return ServiceManager.getService(project, DirDiffManager.class); } - public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2); + public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings); public abstract boolean canShow(@NotNull DiffElement dir1, @NotNull DiffElement dir2); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java index 80242e511937..c75e55e6772b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java @@ -15,8 +15,10 @@ */ package com.intellij.openapi.diff.impl.dir; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.table.JBTable; import javax.swing.*; @@ -25,15 +27,21 @@ import javax.swing.*; */ public class DirDiffDialog extends DialogWrapper { private final DirDiffTableModel myModel; + private final DirDiffSettings mySettings; private DirDiffPanel myDiffPanel; - public DirDiffDialog(Project project, DirDiffTableModel model) { + public DirDiffDialog(Project project, DirDiffTableModel model, DirDiffSettings settings) { super(project); myModel = model; + mySettings = settings; setSize(600, 600); setTitle("Directory Diff"); init(); - myDiffPanel.getTable().changeSelection(myModel.getElementAt(0).isSeparator() ? 1: 0, 3, false, false); + final JBTable table = myDiffPanel.getTable(); + table.changeSelection(myModel.getElementAt(0).isSeparator() ? 1 : 0, 3, false, false); + table.setColumnSelectionAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.getTableHeader().setResizingAllowed(false); } @Override @@ -43,7 +51,7 @@ public class DirDiffDialog extends DialogWrapper { @Override protected JComponent createCenterPanel() { - myDiffPanel = new DirDiffPanel(myModel, this); + myDiffPanel = new DirDiffPanel(myModel, this, mySettings); return myDiffPanel.getPanel(); } 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 28df55a7c9e4..7bd7e8545496 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,7 @@ import com.intellij.ide.diff.DiffElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.sql.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -150,4 +151,8 @@ public class DirDiffElement { } public static enum ElementType {SOURCE, TARGET, SEPARATOR, CHANGED} + + public Icon getIcon() { + return mySource != null ? mySource.getIcon() : myTarget.getIcon(); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java index 4ac2d4119cb0..65bfcb362a6c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.DirDiffManager; import com.intellij.openapi.progress.ProgressIndicator; @@ -23,7 +24,6 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; /** @@ -37,18 +37,18 @@ public class DirDiffManagerImpl extends DirDiffManager { } @Override - public void showDiff(@NotNull final DiffElement dir1, @NotNull final DiffElement dir2) { + public void showDiff(@NotNull final DiffElement dir1, @NotNull final DiffElement dir2, final DirDiffSettings settings) { Task.Backgroundable task = new Task.Backgroundable(myProject, "Directory comparison", true) { @Override public void run(@NotNull ProgressIndicator indicator) { indicator.setText("Calculating differences"); - final DirDiffTableModel model = new DirDiffTableModel(myProject, dir1, dir2, indicator); + final DirDiffTableModel model = new DirDiffTableModel(myProject, dir1, dir2, indicator, settings); final Runnable run = new Runnable() { public void run() { if (model.getRowCount() == 0) { Messages.showInfoMessage(myProject, "No difference has been found", "Directory Diff Tool"); } else { - new DirDiffDialog(myProject, model).show(); + new DirDiffDialog(myProject, model, settings).show(); } } }; 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 3208d4a30ef3..8849338c9002 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 @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.diff.impl.dir.actions.DirDiffToolbarActions; @@ -29,6 +30,7 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -56,7 +58,7 @@ public class DirDiffPanel { private JComponent myViewComponent; private DiffElement myCurrentElement; - public DirDiffPanel(DirDiffTableModel model, DirDiffDialog dirDiffDialog) { + public DirDiffPanel(DirDiffTableModel model, DirDiffDialog dirDiffDialog, DirDiffSettings settings) { myModel = model; myDialog = dirDiffDialog; mySourceDirField.setText(model.getSourceDir().getPath()); @@ -128,11 +130,12 @@ public class DirDiffPanel { } if (0 <= row && row < rows && !myModel.getElementAt(row).isSeparator()) { e.consume(); - myTable.changeSelection(row, 3, false, false); + myTable.changeSelection(row, (myModel.getColumnCount() - 1) / 2, false, false); } } }); - final TableColumn operationColumn = myTable.getColumnModel().getColumn(3); + final TableColumnModel columnModel = myTable.getColumnModel(); + final TableColumn operationColumn = columnModel.getColumn((columnModel.getColumnCount() - 1) / 2); operationColumn.setMaxWidth(25); operationColumn.setMinWidth(25); final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("DirDiff", new DirDiffToolbarActions(myModel), true); 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 2cb81f2ff76e..127c952f1571 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 @@ -78,19 +78,20 @@ public class DirDiffTableCellRenderer extends DefaultTableCellRenderer { } final DirDiffOperation op = element.getOperation(); - if (column == 3) { + if (column == (table.getColumnCount() - 1) / 2) { label.setIcon(op.getIcon()); label.setHorizontalAlignment(CENTER); return label; } else { - label.setIcon(null); + label.setIcon(element.getIcon()); } Color fg = isSelected ? UIUtil.getTableSelectionForeground() : getForegroundColor(op); label.setForeground(fg); - if (column == 2 || column == 4) { + final String name = table.getColumnName(column); + if (DirDiffTableModel.COLUMN_DATE.equals(name)) { label.setHorizontalAlignment(CENTER); - } else if (column == 1 || column == 5) { + } else if (DirDiffTableModel.COLUMN_SIZE.equals(name)) { label.setHorizontalAlignment(RIGHT); label.setText(label.getText() + " "); } else { 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 1eff7a6d7f9c..5c9cebd83e93 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 @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.util.containers.HashSet; @@ -29,26 +30,32 @@ import java.util.*; * @author Konstantin Bulenkov */ public class DirDiffTableModel extends AbstractTableModel { + public static final String COLUMN_NAME = "Name"; + public static final String COLUMN_SIZE = "Size"; + public static final String COLUMN_DATE = "Date"; private final Project myProject; + private final DirDiffSettings mySettings; private DiffElement mySrc; + private HashMap mySrcPaths = new HashMap(); + private HashMap myTrgPaths = new HashMap(); private DiffElement myTrg; final List myElements = new ArrayList(); - private boolean showEqual = false; - private boolean showDifferent = true; - private boolean showNewOnSource = true; - private boolean showNewOnTarget = true; - public DirDiffTableModel(Project project, DiffElement src, DiffElement trg, ProgressIndicator indicator) { + public DirDiffTableModel(Project project, DiffElement src, DiffElement trg, ProgressIndicator indicator, DirDiffSettings settings) { myProject = project; + mySettings = settings; loadModel(src, trg, indicator); } public void loadModel(DiffElement src, DiffElement trg, ProgressIndicator indicator) { mySrc = src; myTrg = trg; + scan("", src, mySrcPaths, indicator, true); + scan("", trg, myTrgPaths, indicator, true); + final HashSet files = new HashSet(); - scan("", src, files, indicator, true); - scan("", trg, files, indicator, true); + files.addAll(mySrcPaths.keySet()); + files.addAll(myTrgPaths.keySet()); final ArrayList pathes = new ArrayList(files); Collections.sort(pathes, new Comparator() { @Override @@ -77,8 +84,8 @@ public class DirDiffTableModel extends AbstractTableModel { }); for (String path : pathes) { - final DiffElement srcFile = src.findFileByRelativePath(path); - final DiffElement trgFile = trg.findFileByRelativePath(path); + final DiffElement srcFile = mySrcPaths.get(path); + final DiffElement trgFile = myTrgPaths.get(path); if (srcFile == null && trgFile != null) { myElements.add(DirDiffElement.createTargetOnly(trgFile)); } else if (srcFile != null && trgFile == null) { @@ -144,18 +151,23 @@ public class DirDiffTableModel extends AbstractTableModel { return myTrg; } - private static void scan(String prefix, DiffElement file, HashSet files, ProgressIndicator indicator, boolean isRoot) { + private static void scan(String prefix, DiffElement file, HashMap files, ProgressIndicator indicator, boolean isRoot) { if (file.isContainer()) { indicator.setText2(file.getPath()); String p = isRoot ? "" : prefix + file.getName() + "/"; if (!isRoot) { - files.add(p); + files.put(p, file); } - for (DiffElement f : file.getChildren()) { - scan(p, f, files, indicator, false); + try { + for (DiffElement f : file.getChildren()) { + scan(p, f, files, indicator, false); + } + } + catch (IOException e) { + //TODO: error message } } else { - files.add(prefix + file.getName()); + files.put(prefix + file.getName(), file); } } @@ -166,7 +178,10 @@ public class DirDiffTableModel extends AbstractTableModel { @Override public int getColumnCount() { - return 7; + int count = 3; + if (mySettings.showDate) count += 2; + if (mySettings.showSize) count += 2; + return count; } @Nullable @@ -176,25 +191,30 @@ public class DirDiffTableModel extends AbstractTableModel { if (element.isSeparator()) { return columnIndex == 0 ? element.getName() : null; } - switch (columnIndex) { - case 0: return element.getSourceName(); - case 1: return element.getSourceSize(); - case 2: return element.getSourceModificationDate(); - case 3: return ""; - case 4: return element.getTargetModificationDate(); - case 5: return element.getTargetSize(); - case 6: return element.getTargetName(); + + final String name = getColumnName(columnIndex); + boolean isSrc = columnIndex < getColumnCount() / 2; + if (name.equals(COLUMN_NAME)) { + return isSrc ? element.getSourceName() : element.getTargetName(); + } else if (name.equals(COLUMN_SIZE)) { + return isSrc ? element.getSourceSize() : element.getTargetSize(); + } else if (name.equals(COLUMN_DATE)) { + return isSrc ? element.getSourceModificationDate() : element.getTargetModificationDate(); } - return null; + return ""; } @Override public String getColumnName(int column) { + final int count = (getColumnCount() - 1) / 2; + if (column == count) return "*"; + if (column > count) { + column = getColumnCount() - 1 - column; + } switch (column) { - case 0: case 6: return "Name"; - case 1: case 5: return "Size"; - case 2: case 4: return "Date"; - case 3: return "*"; + case 0: return COLUMN_NAME; + case 1: return mySettings.showSize ? COLUMN_SIZE : COLUMN_DATE; + case 2: return COLUMN_DATE; } return ""; } @@ -204,34 +224,34 @@ public class DirDiffTableModel extends AbstractTableModel { } public boolean isShowEqual() { - return showEqual; + return mySettings.showEqual; } public void setShowEqual(boolean show) { - this.showEqual = show; + mySettings.showEqual = show; } public boolean isShowDifferent() { - return showDifferent; + return mySettings.showDifferent; } public void setShowDifferent(boolean show) { - this.showDifferent = show; + mySettings.showDifferent = show; } public boolean isShowNewOnSource() { - return showNewOnSource; + return mySettings.showNewOnSource; } public void setShowNewOnSource(boolean show) { - this.showNewOnSource = show; + mySettings.showNewOnSource = show; } public boolean isShowNewOnTarget() { - return showNewOnTarget; + return mySettings.showNewOnTarget; } public void setShowNewOnTarget(boolean show) { - this.showNewOnTarget = show; + mySettings.showNewOnTarget = show; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java index 76c3c07b64de..92112bc1043b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/TestDirDiffAction.java @@ -16,6 +16,7 @@ package com.intellij.openapi.diff.impl.dir; import com.intellij.ide.diff.DiffElement; +import com.intellij.ide.diff.DirDiffSettings; import com.intellij.ide.diff.VirtualFileDiffElement; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -46,7 +47,7 @@ public class TestDirDiffAction extends AnAction { DiffElement elem2 = new VirtualFileDiffElement(files2[0]); final DirDiffManager diffManager = DirDiffManager.getInstance(project); if (diffManager.canShow(elem1, elem2)) { - diffManager.showDiff(elem1, elem2); + diffManager.showDiff(elem1, elem2, new DirDiffSettings()); } } }