mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Handle empty tables.
Cleanup
This commit is contained in:
parent
f8d02a3002
commit
3ef9746d26
@ -32,6 +32,7 @@ DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found
|
||||
DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)
|
||||
DataResultViewerTable.countRender.name=O
|
||||
DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository
|
||||
DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export
|
||||
DataResultViewerTable.firstColLbl=Name
|
||||
DataResultViewerTable.goToPageTextField.err=Invalid page number
|
||||
# {0} - totalPages
|
||||
|
@ -18,12 +18,11 @@
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="outlineView" pref="904" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="exportCSVButton" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pageLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pageNumLabel" min="-2" pref="53" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
|
||||
<Component id="pagesLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="pagePrevButton" linkSize="1" min="-2" pref="16" max="-2" attributes="0"/>
|
||||
@ -33,7 +32,8 @@
|
||||
<Component id="gotoPageLabel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="gotoPageTextField" min="-2" pref="33" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="exportCSVButton" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
|
@ -77,6 +77,7 @@ import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo;
|
||||
@ -176,6 +177,13 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
initComponents();
|
||||
|
||||
initializePagingSupport();
|
||||
|
||||
/*
|
||||
* Disable the CSV export button for the common properties results
|
||||
*/
|
||||
if (this instanceof org.sleuthkit.autopsy.commonpropertiessearch.CommonAttributesSearchResultsViewerTable) {
|
||||
exportCSVButton.setEnabled(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the child OutlineView (explorer view) component.
|
||||
@ -1352,12 +1360,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(exportCSVButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addContainerGap()
|
||||
.addComponent(pageLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addGap(14, 14, 14)
|
||||
.addComponent(pagesLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
@ -1367,7 +1374,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
.addComponent(gotoPageLabel)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(exportCSVButton))
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {pageNextButton, pagePrevButton});
|
||||
@ -1407,8 +1415,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
pagingSupport.gotoPage();
|
||||
}//GEN-LAST:event_gotoPageTextFieldActionPerformed
|
||||
|
||||
@NbBundle.Messages({"DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export"
|
||||
})
|
||||
private void exportCSVButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCSVButtonActionPerformed
|
||||
org.sleuthkit.autopsy.directorytree.ExportCSVAction.saveNodesToCSV(java.util.Arrays.asList(rootNode.getChildren().getNodes()), this);
|
||||
Node currentRoot = this.getExplorerManager().getRootContext();
|
||||
if (currentRoot != null && currentRoot.getChildren().getNodesCount() > 0) {
|
||||
org.sleuthkit.autopsy.directorytree.ExportCSVAction.saveNodesToCSV(java.util.Arrays.asList(currentRoot.getChildren().getNodes()), this);
|
||||
} else {
|
||||
MessageNotifyUtil.Message.info(Bundle.DataResultViewerTable_exportCSVButtonActionPerformed_empty());
|
||||
}
|
||||
}//GEN-LAST:event_exportCSVButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
@ -10,6 +10,7 @@ DirectoryTreeTopComponent.componentOpened.groupDataSources.text=This case contai
|
||||
DirectoryTreeTopComponent.componentOpened.groupDataSources.title=Group by data source?
|
||||
DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.
|
||||
DirectoryTreeTopComponent.resultsView.title=Listing
|
||||
ExportCSV.saveNodesToCSV.empty=No data to export
|
||||
# {0} - Output file
|
||||
ExportCSV.saveNodesToCSV.fileExists=File {0} already exists
|
||||
ExportCSV.saveNodesToCSV.noCurrentCase=No open case available
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013-2018 Basis Technology Corp.
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -22,7 +22,6 @@ import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -31,10 +30,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
@ -48,14 +45,8 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.Utilities;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
|
||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Node.PropertySet;
|
||||
import org.openide.nodes.Node.Property;
|
||||
@ -76,6 +67,12 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
// node in the array returns a reference to the same action object from Node.getActions(boolean).
|
||||
private static ExportCSVAction instance;
|
||||
|
||||
/**
|
||||
* Get an instance of the Action. See above for why
|
||||
* the class is a singleton.
|
||||
*
|
||||
* @return the instance
|
||||
*/
|
||||
public static synchronized ExportCSVAction getInstance() {
|
||||
if (null == instance) {
|
||||
instance = new ExportCSVAction();
|
||||
@ -104,20 +101,28 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
saveNodesToCSV(selectedNodes, (Component)e.getSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the selected nodes to a CSV file
|
||||
*
|
||||
* @param nodesToExport the nodes to save
|
||||
* @param component
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"# {0} - Output file",
|
||||
"ExportCSV.saveNodesToCSV.fileExists=File {0} already exists",
|
||||
"ExportCSV.saveNodesToCSV.noCurrentCase=No open case available"})
|
||||
"ExportCSV.saveNodesToCSV.noCurrentCase=No open case available",
|
||||
"ExportCSV.saveNodesToCSV.empty=No data to export"})
|
||||
public static void saveNodesToCSV(Collection<? extends Node> nodesToExport, Component component) {
|
||||
|
||||
if (nodesToExport.isEmpty()) {
|
||||
MessageNotifyUtil.Message.info(Bundle.ExportCSV_saveNodesToCSV_empty());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Set up the file chooser with a default name and either the Export
|
||||
// folder or the last used folder.
|
||||
String fileName = getDefaultOutputFileName(nodesToExport.iterator().next().getParentNode());
|
||||
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setCurrentDirectory(new File(getExportDirectory(Case.getCurrentCaseThrows())));
|
||||
fileChooser.setSelectedFile(new File(fileName));
|
||||
@ -126,15 +131,18 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
int returnVal = fileChooser.showSaveDialog(component);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
|
||||
// Get the file name, appending .csv if necessary
|
||||
File selectedFile = fileChooser.getSelectedFile();
|
||||
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
||||
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
||||
}
|
||||
|
||||
// Save the directory used for next time
|
||||
updateExportDirectory(selectedFile.getParent(), Case.getCurrentCaseThrows());
|
||||
|
||||
if (selectedFile.exists()) {
|
||||
logger.log(Level.SEVERE, "File {0} already exists", selectedFile.getAbsolutePath()); //NON-NLS
|
||||
MessageNotifyUtil.Message.info(Bundle.ExportCSV_actionPerformed_fileExists(selectedFile));
|
||||
MessageNotifyUtil.Message.info(Bundle.ExportCSV_saveNodesToCSV_fileExists(selectedFile));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -142,7 +150,7 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
writer.execute();
|
||||
}
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
JOptionPane.showMessageDialog(component, Bundle.ExportCSV_actionPerformed_noCurrentCase());
|
||||
JOptionPane.showMessageDialog(component, Bundle.ExportCSV_saveNodesToCSV_noCurrentCase());
|
||||
logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
@ -165,13 +173,10 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
String parentName = prop.getValue().toString();
|
||||
|
||||
// Strip off the count (if present)
|
||||
System.out.println("parentName (raw) : " + parentName);
|
||||
parentName = parentName.replaceAll("\\([0-9]+\\)$", "");
|
||||
System.out.println("parentName (after paren regex) : " + parentName);
|
||||
|
||||
// Strip out any invalid characters
|
||||
parentName = parentName.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
System.out.println("parentName (after char regex) : " + parentName);
|
||||
|
||||
return parentName + " " + dateStr;
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
@ -190,7 +195,7 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
*
|
||||
* @return The export directory path.
|
||||
*/
|
||||
private static String getExportDirectory(Case openCase) { // TODO sync
|
||||
private static String getExportDirectory(Case openCase) {
|
||||
String caseExportPath = openCase.getExportDirectory();
|
||||
|
||||
if (userDefinedExportPath == null) {
|
||||
@ -306,6 +311,13 @@ public final class ExportCSVAction extends AbstractAction {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert list of values to a comma separated string.
|
||||
*
|
||||
* @param values Values to convert
|
||||
*
|
||||
* @return values as CSV
|
||||
*/
|
||||
private String listToCSV(List<String> values) {
|
||||
return "\"" + String.join("\",\"", values) + "\"\n";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user