From 35879f85ec2476b94327ca77d03514255899b8e2 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 21 Oct 2013 16:21:09 +0400 Subject: [PATCH] [log] Create NoGraphTableModel for future filtering Some filters will be unable to work on graph, therefore we introducing special renderer and special table model for them. * Move common stuff to the AbstractVcsLogTableModel. * Introduce NoGraphTableModel. Just store the list of commits there. There will be not many of them, performance should be OK. * Fix the Root renderer in the VcsLogGraphTable to get the root from value, not from the node. --- .../vcs/log/ui/frame/VcsLogGraphTable.java | 47 +++---- .../ui/tables/AbstractVcsLogTableModel.java | 98 ++++++++++++++ .../vcs/log/ui/tables/GraphTableModel.java | 123 ++++++------------ .../vcs/log/ui/tables/NoGraphTableModel.java | 89 +++++++++++++ 4 files changed, 255 insertions(+), 102 deletions(-) create mode 100644 platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java create mode 100644 platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java index 8ef5f0c7879b..dc2785352a2f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java @@ -10,14 +10,14 @@ import com.intellij.vcs.log.data.VcsLogDataHolder; import com.intellij.vcs.log.graph.elements.Edge; import com.intellij.vcs.log.graph.elements.GraphElement; import com.intellij.vcs.log.graph.elements.Node; -import com.intellij.vcs.log.graph.render.GraphCellPainter; -import com.intellij.vcs.log.graph.render.GraphCommitCell; -import com.intellij.vcs.log.graph.render.PositionUtil; -import com.intellij.vcs.log.graph.render.SimpleGraphCellPainter; +import com.intellij.vcs.log.graph.render.*; import com.intellij.vcs.log.printmodel.GraphPrintCell; import com.intellij.vcs.log.printmodel.SpecialPrintElement; import com.intellij.vcs.log.ui.VcsLogUI; +import com.intellij.vcs.log.ui.render.AbstractPaddingCellRender; +import com.intellij.vcs.log.ui.render.CommitCellRender; import com.intellij.vcs.log.ui.render.GraphCommitCellRender; +import com.intellij.vcs.log.ui.tables.AbstractVcsLogTableModel; import com.intellij.vcs.log.ui.tables.GraphTableModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -52,8 +52,9 @@ public class VcsLogGraphTable extends JBTable { myUI = UI; setTableHeader(null); - setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI, logDataHolder)); + setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI)); setDefaultRenderer(GraphCommitCell.class, new GraphCommitCellRender(myGraphPainter, logDataHolder, myUI.getColorManager())); + setDefaultRenderer(CommitCell.class, new CommitCellRender(myUI.getColorManager())); setDefaultRenderer(String.class, new StringCellRenderer()); setRowHeight(HEIGHT_CELL); @@ -76,16 +77,16 @@ public class VcsLogGraphTable extends JBTable { } public void setPreferredColumnWidths() { - TableColumn rootColumn = getColumnModel().getColumn(GraphTableModel.ROOT_COLUMN); + TableColumn rootColumn = getColumnModel().getColumn(AbstractVcsLogTableModel.ROOT_COLUMN); int rootWidth = myUI.getColorManager().isMultipleRoots() ? ROOT_INDICATOR_WIDTH : 0; // NB: all further instructions and their order are important, otherwise the minimum size which is less than 15 won't be applied rootColumn.setMinWidth(rootWidth); rootColumn.setMaxWidth(rootWidth); rootColumn.setPreferredWidth(rootWidth); - getColumnModel().getColumn(GraphTableModel.COMMIT_COLUMN).setPreferredWidth(700); - getColumnModel().getColumn(GraphTableModel.AUTHOR_COLUMN).setMinWidth(90); - getColumnModel().getColumn(GraphTableModel.DATE_COLUMN).setMinWidth(90); + getColumnModel().getColumn(AbstractVcsLogTableModel.COMMIT_COLUMN).setPreferredWidth(700); + getColumnModel().getColumn(AbstractVcsLogTableModel.AUTHOR_COLUMN).setMinWidth(90); + getColumnModel().getColumn(AbstractVcsLogTableModel.DATE_COLUMN).setMinWidth(90); } public void jumpToRow(int rowIndex) { @@ -99,14 +100,18 @@ public class VcsLogGraphTable extends JBTable { if (rowIndex >= model.getRowCount()) { return null; } - GraphCommitCell commitCell = (GraphCommitCell)model.getValueAt(rowIndex, GraphTableModel.COMMIT_COLUMN); - return commitCell.getPrintCell(); + Object commitValue = model.getValueAt(rowIndex, AbstractVcsLogTableModel.COMMIT_COLUMN); + if (commitValue instanceof GraphCommitCell) { + GraphCommitCell commitCell = (GraphCommitCell)commitValue; + return commitCell.getPrintCell(); + } + return null; } @Nullable public List getSelectedChanges() { TableModel model = getModel(); - if (!(model instanceof GraphTableModel)) { + if (!(model instanceof AbstractVcsLogTableModel)) { LOG.error("Unexpected table model passed to the VcsLogGraphTable: " + model); return null; } @@ -193,13 +198,11 @@ public class VcsLogGraphTable extends JBTable { private static final Logger LOG = Logger.getInstance(RootCellRenderer.class); @NotNull private final VcsLogUI myUi; - @NotNull private final VcsLogDataHolder myDataHolder; @NotNull private Color myColor = UIUtil.getTableBackground(); - RootCellRenderer(@NotNull VcsLogUI ui, @NotNull VcsLogDataHolder dataHolder) { + RootCellRenderer(@NotNull VcsLogUI ui) { myUi = ui; - myDataHolder = dataHolder; } @Override @@ -212,12 +215,12 @@ public class VcsLogGraphTable extends JBTable { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Node commitNode = myDataHolder.getDataPack().getGraphModel().getGraph().getCommitNodeInRow(row); - if (commitNode == null) { - LOG.warn("Commit node not found for row " + row); + if (value instanceof VirtualFile) { + myColor = myUi.getColorManager().getRootColor((VirtualFile)value); } else { - myColor = myUi.getColorManager().getRootColor(commitNode.getBranch().getRepositoryRoot()); + LOG.error("Incorrect value " + value + " specified in row #" + row + ", column #"); + myColor = UIUtil.getTableBackground(isSelected); } return this; } @@ -227,10 +230,10 @@ public class VcsLogGraphTable extends JBTable { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - Object commit = getValueAt(row, GraphTableModel.COMMIT_COLUMN); + Object commit = getValueAt(row, AbstractVcsLogTableModel.COMMIT_COLUMN); if (commit instanceof GraphCommitCell) { - if (GraphCommitCellRender.isMarked(commit) && !isSelected) { - rendererComponent.setBackground(GraphCommitCellRender.MARKED_BACKGROUND); + if (AbstractPaddingCellRender.isMarked(commit) && !isSelected) { + rendererComponent.setBackground(AbstractPaddingCellRender.MARKED_BACKGROUND); } else { setBackground(isSelected ? table.getSelectionBackground() : JBColor.WHITE); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java new file mode 100644 index 000000000000..442798347e7b --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java @@ -0,0 +1,98 @@ +package com.intellij.vcs.log.ui.tables; + +import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile; +import com.intellij.util.text.DateFormatUtil; +import com.intellij.vcs.log.VcsShortCommitDetails; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +/** + * @param commit column class + */ +public abstract class AbstractVcsLogTableModel extends AbstractTableModel { + + public static final VirtualFile UNKNOWN_ROOT = NullVirtualFile.INSTANCE; + + public static final int ROOT_COLUMN = 0; + public static final int COMMIT_COLUMN = 1; + public static final int AUTHOR_COLUMN = 2; + public static final int DATE_COLUMN = 3; + private static final int COLUMN_COUNT = DATE_COLUMN + 1; + + private static final String[] COLUMN_NAMES = {"Root", "Subject", "Author", "Date"}; + + @Override + public final int getColumnCount() { + return COLUMN_COUNT; + } + + @Nullable + protected abstract VcsShortCommitDetails getShortDetails(int rowIndex); + + @NotNull + @Override + public final Object getValueAt(int rowIndex, int columnIndex) { + VcsShortCommitDetails data = getShortDetails(rowIndex); + switch (columnIndex) { + case ROOT_COLUMN: + return getRoot(rowIndex); + case COMMIT_COLUMN: + return getCommitColumnCell(rowIndex, data); + case AUTHOR_COLUMN: + if (data == null) { + return ""; + } + else { + return data.getAuthorName(); + } + case DATE_COLUMN: + if (data == null) { + return ""; + } + else { + return DateFormatUtil.formatDateTime(data.getAuthorTime()); + } + default: + throw new IllegalArgumentException("columnIndex is " + columnIndex + " > " + (COLUMN_COUNT - 1)); + } + } + + @Nullable + public abstract List getSelectedChanges(int[] selectedRows); + + @NotNull + protected abstract VirtualFile getRoot(int rowIndex); + + @NotNull + protected abstract T getCommitColumnCell(int index, @Nullable VcsShortCommitDetails details); + + @NotNull + protected abstract Class getCommitColumnClass(); + + @Override + public Class getColumnClass(int column) { + switch (column) { + case ROOT_COLUMN: + return VirtualFile.class; + case COMMIT_COLUMN: + return getCommitColumnClass(); + case AUTHOR_COLUMN: + return String.class; + case DATE_COLUMN: + return String.class; + default: + throw new IllegalArgumentException("columnIndex is " + column + " > " + (COLUMN_COUNT - 1)); + } + } + + @Override + public String getColumnName(int column) { + return COLUMN_NAMES[column]; + } + +} diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java index 1378e964563d..94da3b8d7824 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java @@ -1,9 +1,9 @@ package com.intellij.vcs.log.ui.tables; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.text.DateFormatUtil; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.VcsRef; import com.intellij.vcs.log.VcsShortCommitDetails; @@ -17,21 +17,17 @@ import com.intellij.vcs.log.printmodel.GraphPrintCell; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.table.AbstractTableModel; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** - * @author erokhins + * @author Kirill Likhodedov */ -public class GraphTableModel extends AbstractTableModel { +public class GraphTableModel extends AbstractVcsLogTableModel { - public static final int ROOT_COLUMN = 0; - public static final int COMMIT_COLUMN = 1; - public static final int AUTHOR_COLUMN = 2; - public static final int DATE_COLUMN = 3; - private static final int COLUMN_COUNT = DATE_COLUMN + 1; - - private static final String[] COLUMN_NAMES = {"Root", "Subject", "Author", "Date"}; + private static final Logger LOG = Logger.getInstance(GraphTableModel.class); @NotNull private final DataPack myDataPack; @NotNull private final VcsLogDataHolder myDataHolder; @@ -46,79 +42,15 @@ public class GraphTableModel extends AbstractTableModel { return myDataPack.getGraphModel().getGraph().getNodeRows().size(); } + @Nullable @Override - public int getColumnCount() { - return COLUMN_COUNT; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { + protected VcsShortCommitDetails getShortDetails(int rowIndex) { Node commitNode = myDataPack.getGraphModel().getGraph().getCommitNodeInRow(rowIndex); - VcsShortCommitDetails data; - if (commitNode == null) { - data = null; - } - else { - data = myDataHolder.getMiniDetailsGetter().getCommitData(commitNode); - } - switch (columnIndex) { - case ROOT_COLUMN: - if (commitNode != null) { - return commitNode.getBranch().getRepositoryRoot(); - } - else { - return null; - } - case COMMIT_COLUMN: - GraphPrintCell graphPrintCell = myDataPack.getPrintCellModel().getGraphPrintCell(rowIndex); - String message = ""; - Collection refs = Collections.emptyList(); - if (data != null) { - message = data.getSubject(); - refs = myDataPack.getRefsModel().refsToCommit(data.getHash()); - } - return new GraphCommitCell(graphPrintCell, message, refs); - case AUTHOR_COLUMN: - if (data == null) { - return ""; - } - else { - return data.getAuthorName(); - } - case DATE_COLUMN: - if (data == null) { - return ""; - } - else { - return DateFormatUtil.formatDateTime(data.getAuthorTime()); - } - default: - throw new IllegalArgumentException("columnIndex is " + columnIndex + " > " + (COLUMN_COUNT - 1)); - } - } - - @Override - public Class getColumnClass(int column) { - switch (column) { - case ROOT_COLUMN: - return VirtualFile.class; - case COMMIT_COLUMN: - return GraphCommitCell.class; - case AUTHOR_COLUMN: - return String.class; - case DATE_COLUMN: - return String.class; - default: - throw new IllegalArgumentException("columnIndex is " + column + " > " + (COLUMN_COUNT - 1)); - } - } - - @Override - public String getColumnName(int column) { - return COLUMN_NAMES[column]; + return commitNode == null ? null : myDataHolder.getMiniDetailsGetter().getCommitData(commitNode); } @Nullable + @Override public List getSelectedChanges(int[] selectedRows) { List changes = new ArrayList(); for (Node node : nodes(selectedRows)) { @@ -154,4 +86,35 @@ public class GraphTableModel extends AbstractTableModel { return null; } + @NotNull + @Override + protected VirtualFile getRoot(int rowIndex) { + Node commitNode = myDataPack.getGraphModel().getGraph().getCommitNodeInRow(rowIndex); + if (commitNode != null) { + return commitNode.getBranch().getRepositoryRoot(); + } + else { + LOG.error("Couldn't identify commit node at " + rowIndex); + return UNKNOWN_ROOT; + } + } + + @NotNull + @Override + protected GraphCommitCell getCommitColumnCell(int rowIndex, @Nullable VcsShortCommitDetails details) { + GraphPrintCell graphPrintCell = myDataPack.getPrintCellModel().getGraphPrintCell(rowIndex); + String message = ""; + List refs = Collections.emptyList(); + if (details != null) { + message = details.getSubject(); + refs = (List)myDataPack.getRefsModel().refsToCommit(details.getHash()); + } + return new GraphCommitCell(graphPrintCell, message, refs); + } + + @NotNull + @Override + protected Class getCommitColumnClass() { + return GraphCommitCell.class; + } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java new file mode 100644 index 000000000000..c067936be9cd --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java @@ -0,0 +1,89 @@ +package com.intellij.vcs.log.ui.tables; + +import com.intellij.openapi.diagnostic.Attachment; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.vcs.log.VcsFullCommitDetails; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.VcsShortCommitDetails; +import com.intellij.vcs.log.data.RefsModel; +import com.intellij.vcs.log.graph.render.CommitCell; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class NoGraphTableModel extends AbstractVcsLogTableModel { + + private static final Logger LOG = Logger.getInstance(NoGraphTableModel.class); + @NotNull private final List> myCommitsWithRoots; + @NotNull private final RefsModel myRefsModel; + + public NoGraphTableModel(@NotNull List> commitsWithRoots, @NotNull RefsModel refsModel) { + myCommitsWithRoots = commitsWithRoots; + myRefsModel = refsModel; + } + + @Override + public int getRowCount() { + return myCommitsWithRoots.size(); + } + + @Nullable + @Override + protected VcsShortCommitDetails getShortDetails(int rowIndex) { + Pair commitAndRoot = myCommitsWithRoots.get(rowIndex); + if (commitAndRoot != null) { + return commitAndRoot.getFirst(); + } + else { + LOG.error("Couldn't identify details for commit at " + rowIndex, new Attachment("loaded_commits", myCommitsWithRoots.toString())); + return null; + } + } + + @Nullable + @Override + public List getSelectedChanges(int[] selectedRows) { + Arrays.sort(selectedRows); + List changes = new ArrayList(); + for (int selectedRow : selectedRows) { + changes.addAll(myCommitsWithRoots.get(selectedRow).getFirst().getChanges()); + } + return changes; + } + + @NotNull + @Override + protected VirtualFile getRoot(int rowIndex) { + Pair commitAndRoot = myCommitsWithRoots.get(rowIndex); + if (commitAndRoot != null) { + return commitAndRoot.getSecond(); + } + else { + LOG.error("Couldn't identify root for commit at " + rowIndex, new Attachment("loaded_commits", myCommitsWithRoots.toString())); + return UNKNOWN_ROOT; + } + } + + @NotNull + @Override + protected CommitCell getCommitColumnCell(int index, @Nullable VcsShortCommitDetails details) { + String subject = ""; + Collection refs = Collections.emptyList(); + if (details != null) { + subject = details.getSubject(); + refs = myRefsModel.refsToCommit(details.getHash()); + } + return new CommitCell(subject, refs); + } + + @NotNull + @Override + protected Class getCommitColumnClass() { + return CommitCell.class; + } + +}