1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-04 06:50:00 +00:00

Merge pull request #2793 from millmanorama/2210-persist-sort

2210 persist sort
This commit is contained in:
Richard Cordovano
2017-05-10 15:24:35 -04:00
committed by GitHub

View File

@@ -26,15 +26,19 @@ import java.awt.Graphics;
import java.awt.dnd.DnDConstants;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.FeatureDescriptor;
import java.beans.PropertyChangeEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.prefs.Preferences;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
@@ -43,6 +47,8 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.netbeans.swing.etable.ETableColumn;
import org.netbeans.swing.outline.DefaultOutlineCellRenderer;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.openide.explorer.ExplorerManager;
@@ -88,6 +94,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
// the column started and where it ended up.
private int startColumnIndex = -1;
private int endColumnIndex = -1;
private OutlineView ov;
/**
* Creates a DataResultViewerTable object that is compatible with node
@@ -111,7 +118,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
private void initialize() {
initComponents();
OutlineView ov = ((OutlineView) this.tableScrollPanel);
ov = ((OutlineView) this.tableScrollPanel);
ov.setAllowedDragActions(DnDConstants.ACTION_NONE);
ov.getOutline().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
@@ -216,6 +223,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
}
startColumnIndex = -1;
}
@Override
public void mouseClicked(MouseEvent e) {
storeState();
}
});
}
@@ -363,13 +375,9 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
private void setupTable(final Node root) {
em.setRootContext(root);
final OutlineView ov = ((OutlineView) this.tableScrollPanel);
if (ov == null) {
return;
}
currentRoot = root;
List<Node.Property<?>> props = loadState();
List<Node.Property<?>> props = loadColumnOrder();
/**
* OutlineView makes the first column be the result of
@@ -390,14 +398,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
// Get the columns setup with respect to names and sortability
String[] propStrings = new String[props.size() * 2];
for (int i = 0; i < props.size(); i++) {
props.get(i).setValue("ComparableColumnTTV", Boolean.TRUE); //NON-NLS
final Property<?> prop = props.get(i);
prop.setValue("ComparableColumnTTV", Boolean.TRUE); //NON-NLS
//First property column is sorted initially
if (i == 0) {
props.get(i).setValue("TreeColumnTTV", Boolean.TRUE); // Identifies special property representing first (tree) column. NON-NLS
props.get(i).setValue("SortingColumnTTV", Boolean.TRUE); // TreeTableView should be initially sorted by this property column. NON-NLS
prop.setValue("TreeColumnTTV", Boolean.TRUE); // Identifies special property representing first (tree) column. NON-NLS
prop.setValue("SortingColumnTTV", Boolean.TRUE); // TreeTableView should be initially sorted by this property column. NON-NLS
}
propStrings[2 * i] = props.get(i).getName();
propStrings[2 * i + 1] = props.get(i).getDisplayName();
propStrings[2 * i] = prop.getName();
propStrings[2 * i + 1] = prop.getDisplayName();
}
ov.setPropertyColumns(propStrings);
@@ -442,6 +451,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
loadSort();
/**
* This custom renderer extends the renderer that was already being used
* by the outline table. This renderer colors a row if the tags property
@@ -494,19 +505,73 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
if (currentRoot == null || propertiesMap.isEmpty()) {
return;
}
TableFilterNode tfn;
if (currentRoot instanceof TableFilterNode) {
tfn = (TableFilterNode) currentRoot;
} else {
TableFilterNode tfn = (TableFilterNode) currentRoot;
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
// Store the current order of the columns into settings
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
preferences.put(getColumnPositionKey(tfn.getColumnOrderKey(), entry.getValue().getName()), String.valueOf(entry.getKey()));
}
final TableColumnModel columnModel = ov.getOutline().getColumnModel();
//store the sorting information
int numCols = columnModel.getColumnCount();
for (int i = 0; i < numCols; i++) {
ETableColumn etc = (ETableColumn) columnModel.getColumn(i);
String columnName = ov.getOutline().getColumnName(i);
if (etc.isSorted()) {
preferences.put(getColumnSortOrderKey(tfn.getColumnOrderKey(), columnName), String.valueOf(etc.isAscending()));
preferences.put(getColumnSortRankKey(tfn.getColumnOrderKey(), columnName), String.valueOf(etc.getSortRank()));
} else {
preferences.remove(getColumnSortOrderKey(tfn.getColumnOrderKey(), columnName));
preferences.remove(getColumnSortRankKey(tfn.getColumnOrderKey(), columnName));
}
}
}
}
static private final class ColumnSortInfo {
private final int modelIndex;
private final int rank;
private final boolean order;
private ColumnSortInfo(int modelIndex, int rank, boolean order) {
this.modelIndex = modelIndex;
this.rank = rank;
this.order = order;
}
private int getRank() {
return rank;
}
}
private synchronized void loadSort() {
if (currentRoot == null || propertiesMap.isEmpty()) {
return;
}
// Store the current order of the columns into settings
for (Map.Entry<Integer, Property<?>> entry : propertiesMap.entrySet()) {
Property<?> prop = entry.getValue();
int storeValue = entry.getKey();
NbPreferences.forModule(this.getClass()).put(getColumnPreferenceKey(prop, tfn.getColumnOrderKey()), String.valueOf(storeValue));
if (currentRoot instanceof TableFilterNode) {
final String columnOrderKey = ((TableFilterNode) currentRoot).getColumnOrderKey();
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
//organize property sorting information, sorted by rank
TreeSet<ColumnSortInfo> treeSet = new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank));
propertiesMap.entrySet().stream()
.forEach(entry -> {
final String propName = entry.getValue().getName();
//if the sort rank is undefined, it will be defaulted to 0 => unsorted.
Integer sortRank = Integer.valueOf(preferences.get(getColumnSortRankKey(columnOrderKey, propName), "0"));
//default to true => ascending
Boolean sortOrder = Boolean.valueOf(preferences.get(getColumnSortOrderKey(columnOrderKey, propName), "true"));
treeSet.add(new ColumnSortInfo(entry.getKey(), sortRank, sortOrder));
});
//apply sort information in rank order.
treeSet.forEach(sortInfo -> ov.getOutline().setColumnSorted(sortInfo.modelIndex, sortInfo.order, sortInfo.rank));
}
}
@@ -515,7 +580,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
*
* @return a List<Node.Property<?>> of the preferences in order
*/
private synchronized List<Node.Property<?>> loadState() {
private synchronized List<Node.Property<?>> loadColumnOrder() {
// This is a set because we add properties of up to 100 child nodes, and we want unique properties
Set<Property<?>> propertiesAcc = new LinkedHashSet<>();
this.getAllChildPropertyHeadersRec(currentRoot, 100, propertiesAcc);
@@ -540,8 +605,10 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
*/
int offset = props.size();
boolean noPreviousSettings = true;
final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class);
for (Property<?> prop : props) {
Integer value = Integer.valueOf(NbPreferences.forModule(this.getClass()).get(getColumnPreferenceKey(prop, tfn.getColumnOrderKey()), "-1"));
Integer value = Integer.valueOf(preferences.get(getColumnPositionKey(tfn.getColumnOrderKey(), prop.getName()), "-1"));
if (value >= 0 && value < offset && !propertiesMap.containsKey(value)) {
propertiesMap.put(value, prop);
noPreviousSettings = false;
@@ -573,9 +640,24 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
*
* @return A generated key for the preference file
*/
private String getColumnPreferenceKey(Property<?> prop, String type) {
return type.replaceAll("[^a-zA-Z0-9_]", "") + "."
+ prop.getName().replaceAll("[^a-zA-Z0-9_]", "") + ".column";
private String getColumnPositionKey(String type, String propName) {
return getColumnKeyBase(type, propName) + ".column";
}
private String getColumnSortOrderKey(String type, String propName) {
return getColumnKeyBase(type, propName) + ".sortOrder";
}
private String getColumnSortRankKey(String type, String propName) {
return getColumnKeyBase(type, propName) + ".sortRank";
}
private static String getColumnKeyBase(String type, String propName) {
return stripNonAlphanumeric(type) + "." + stripNonAlphanumeric(propName);
}
private static String stripNonAlphanumeric(String str) {
return str.replaceAll("[^a-zA-Z0-9_]", "");
}
@Override