Db Diff support + API changes for Dir Diff

This commit is contained in:
Konstantin Bulenkov
2011-04-14 19:30:07 +04:00
parent 285ffc8714
commit 43b1f29b4d
9 changed files with 111 additions and 54 deletions
@@ -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<T> {
public static final DiffElement[] EMPTY_ARRAY = new DiffElement[0];
private DiffPanel myDiffPanel;
private Editor myEditor;
@@ -54,7 +57,7 @@ public abstract class DiffElement<T> {
public abstract boolean isContainer();
public abstract DiffElement<T>[] getChildren();
public abstract DiffElement[] getChildren() throws IOException;
@Nullable
public abstract DiffElement<T> findFileByRelativePath(String path);
@@ -67,6 +70,10 @@ public abstract class DiffElement<T> {
@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<T> {
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<T> {
@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<T> {
myDiffPanel = null;
}
}
public String getSeparator() {
return "/";
}
@Nullable
public Icon getIcon() {
return null;
}
}
@@ -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);
}
@@ -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();
}
@@ -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();
}
}
@@ -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();
}
}
};
@@ -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);
@@ -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 {
@@ -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<String, DiffElement> mySrcPaths = new HashMap<String, DiffElement>();
private HashMap<String, DiffElement> myTrgPaths = new HashMap<String, DiffElement>();
private DiffElement myTrg;
final List<DirDiffElement> myElements = new ArrayList<DirDiffElement>();
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<String> files = new HashSet<String>();
scan("", src, files, indicator, true);
scan("", trg, files, indicator, true);
files.addAll(mySrcPaths.keySet());
files.addAll(myTrgPaths.keySet());
final ArrayList<String> pathes = new ArrayList<String>(files);
Collections.sort(pathes, new Comparator<String>() {
@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<String> files, ProgressIndicator indicator, boolean isRoot) {
private static void scan(String prefix, DiffElement file, HashMap<String, DiffElement> 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;
}
}
@@ -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());
}
}
}