mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
5372 initial video thumbnail viewer
This commit is contained in:
parent
6da2310384
commit
ab6abbe29a
@ -56,3 +56,4 @@ ResultsPanel.currentPageLabel.text=Page: -
|
||||
ResultsPanel.pageControlsLabel.text=Pages:
|
||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||
ResultsPanel.pageSizeLabel.text=Page size:
|
||||
ThumbnailPanel.fileInfoLabel.text=
|
||||
|
@ -164,3 +164,4 @@ ResultsPanel.pageControlsLabel.text=Pages:
|
||||
ResultsPanel.gotoPageLabel.text=Go to Page:
|
||||
ResultsPanel.pageSizeLabel.text=Page size:
|
||||
SearchNode.getName.text=Search Result
|
||||
ThumbnailPanel.fileInfoLabel.text=
|
||||
|
@ -24,10 +24,9 @@ import java.util.List;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Class to handle envent bus and events for file discovery tool.
|
||||
* Class to handle event bus and events for file discovery tool.
|
||||
*/
|
||||
final class DiscoveryEvents {
|
||||
|
||||
@ -156,7 +155,7 @@ final class DiscoveryEvents {
|
||||
*/
|
||||
static final class PageRetrievedEvent {
|
||||
|
||||
private final List<AbstractFile> results;
|
||||
private final List<ResultFile> results;
|
||||
private final int page;
|
||||
private final FileType resultType;
|
||||
|
||||
@ -167,7 +166,7 @@ final class DiscoveryEvents {
|
||||
* @param page The number of the page which was retrieved.
|
||||
* @param results The list of files in the page retrieved.
|
||||
*/
|
||||
PageRetrievedEvent(FileType resultType, int page, List<AbstractFile> results) {
|
||||
PageRetrievedEvent(FileType resultType, int page, List<ResultFile> results) {
|
||||
this.results = results;
|
||||
this.page = page;
|
||||
this.resultType = resultType;
|
||||
@ -178,7 +177,7 @@ final class DiscoveryEvents {
|
||||
*
|
||||
* @return The list of files in the page retrieved.
|
||||
*/
|
||||
List<AbstractFile> getSearchResults() {
|
||||
List<ResultFile> getSearchResults() {
|
||||
return Collections.unmodifiableList(results);
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,8 @@ class FileGroup implements Comparable<FileGroup> {
|
||||
*
|
||||
* @return List of abstract files
|
||||
*/
|
||||
List<AbstractFile> getAbstractFiles() {
|
||||
return files.stream().map(file -> file.getAbstractFile()).collect(Collectors.toList());
|
||||
List<ResultFile> getAbstractFiles() {
|
||||
return Collections.unmodifiableList(files);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +57,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
class FileSearch {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(FileSearch.class.getName());
|
||||
private static final Cache<String, List<AbstractFile>> groupCache = CacheBuilder.newBuilder().build();
|
||||
private static final Cache<String, List<ResultFile>> groupCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
/**
|
||||
* Run the file search and returns the SearchResults object for debugging.
|
||||
@ -104,7 +104,7 @@ class FileSearch {
|
||||
|
||||
// Sort and group the results
|
||||
searchResults.sortGroupsAndFiles();
|
||||
LinkedHashMap<String, List<AbstractFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
LinkedHashMap<String, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (String groupName : resultHashMap.keySet()) {
|
||||
groupCache.put(groupName, resultHashMap.get(groupName));
|
||||
}
|
||||
@ -134,7 +134,7 @@ class FileSearch {
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
FileSorter.SortingMethod fileSortingMethod,
|
||||
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||
LinkedHashMap<String, List<AbstractFile>> searchResults = runFileSearch(filters,
|
||||
LinkedHashMap<String, List<ResultFile>> searchResults = runFileSearch(filters,
|
||||
groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||
LinkedHashMap<String, Integer> groupSizes = new LinkedHashMap<>();
|
||||
for (String groupName : searchResults.keySet()) {
|
||||
@ -163,7 +163,7 @@ class FileSearch {
|
||||
*
|
||||
* @throws FileSearchException
|
||||
*/
|
||||
static synchronized List<AbstractFile> getFilesInGroup(
|
||||
static synchronized List<ResultFile> getFilesInGroup(
|
||||
List<FileSearchFiltering.FileFilter> filters,
|
||||
AttributeType groupAttributeType,
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
@ -173,8 +173,8 @@ class FileSearch {
|
||||
int numberOfEntries,
|
||||
SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||
//the group should be in the cache at this point
|
||||
List<AbstractFile> filesInGroup = groupCache.getIfPresent(groupName);
|
||||
List<AbstractFile> page = new ArrayList<>();
|
||||
List<ResultFile> filesInGroup = groupCache.getIfPresent(groupName);
|
||||
List<ResultFile> page = new ArrayList<>();
|
||||
if (filesInGroup == null) {
|
||||
logger.log(Level.INFO, "Group {0} was not cached, performing search to cache all groups again", groupName);
|
||||
runFileSearch(filters, groupAttributeType, groupSortingType, fileSortingMethod, caseDb, centralRepoDb);
|
||||
@ -214,7 +214,7 @@ class FileSearch {
|
||||
*
|
||||
* @throws FileSearchException
|
||||
*/
|
||||
private synchronized static LinkedHashMap<String, List<AbstractFile>> runFileSearch(
|
||||
private synchronized static LinkedHashMap<String, List<ResultFile>> runFileSearch(
|
||||
List<FileSearchFiltering.FileFilter> filters,
|
||||
AttributeType groupAttributeType,
|
||||
FileGroup.GroupSortingAlgorithm groupSortingType,
|
||||
@ -239,7 +239,7 @@ class FileSearch {
|
||||
// Collect everything in the search results
|
||||
SearchResults searchResults = new SearchResults(groupSortingType, groupAttributeType, fileSortingMethod);
|
||||
searchResults.add(resultFiles);
|
||||
LinkedHashMap<String, List<AbstractFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
LinkedHashMap<String, List<ResultFile>> resultHashMap = searchResults.toLinkedHashMap();
|
||||
for (String groupName : resultHashMap.keySet()) {
|
||||
groupCache.put(groupName, resultHashMap.get(groupName));
|
||||
}
|
||||
@ -361,6 +361,7 @@ class FileSearch {
|
||||
*/
|
||||
void addAttributeToResultFiles(List<ResultFile> files, SleuthkitCase caseDb, EamDb centralRepoDb) throws FileSearchException {
|
||||
// Default is to do nothing
|
||||
System.out.println("DEFAULT IMPLE ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@ -33,7 +32,6 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Class to test the file search API. Allows the user to run searches and see results.
|
||||
@ -106,7 +104,7 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
||||
if (! groups.isEmpty()) {
|
||||
String firstGroupName = groups.keySet().iterator().next();
|
||||
|
||||
List<AbstractFile> entries0to5 = FileSearch.getFilesInGroup(filters,
|
||||
List<ResultFile> entries0to5 = FileSearch.getFilesInGroup(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
@ -115,11 +113,11 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
||||
5,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
System.out.println("First five " + firstGroupName + " : ");
|
||||
for (AbstractFile f : entries0to5) {
|
||||
System.out.println(" " + f.getName());
|
||||
for (ResultFile f : entries0to5) {
|
||||
System.out.println(" " + f.getAbstractFile().getName());
|
||||
}
|
||||
|
||||
List<AbstractFile> entries6to106 = FileSearch.getFilesInGroup(filters,
|
||||
List<ResultFile> entries6to106 = FileSearch.getFilesInGroup(filters,
|
||||
groupingAttr,
|
||||
groupSortAlgorithm,
|
||||
fileSort,
|
||||
@ -128,8 +126,8 @@ public final class FileSearchTestAction extends CallableSystemAction {
|
||||
100,
|
||||
Case.getCurrentCase().getSleuthkitCase(), crDb);
|
||||
System.out.println(firstGroupName + " 6 to 106: ");
|
||||
for (AbstractFile f : entries6to106) {
|
||||
System.out.println(" " + f.getName());
|
||||
for (ResultFile f : entries6to106) {
|
||||
System.out.println(" " + f.getAbstractFile().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ final class PageWorker extends SwingWorker<Void, Void> {
|
||||
|
||||
try {
|
||||
// Run the search
|
||||
List<AbstractFile> results = FileSearch.getFilesInGroup(searchfilters,
|
||||
List<ResultFile> results = FileSearch.getFilesInGroup(searchfilters,
|
||||
groupingAttribute,
|
||||
groupSort,
|
||||
fileSortMethod, groupName, startingEntry, pageSize,
|
||||
|
@ -18,12 +18,14 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
|
||||
import java.awt.Image;
|
||||
import org.sleuthkit.autopsy.filequery.FileSearchData.FileType;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.autopsy.coreutils.ImageUtils;
|
||||
import org.sleuthkit.datamodel.HashUtility;
|
||||
|
||||
/**
|
||||
@ -38,6 +40,7 @@ class ResultFile {
|
||||
private final List<String> tagNames;
|
||||
private final List<String> interestingSetNames;
|
||||
private final List<String> objectDetectedNames;
|
||||
private final List<Image> thumbnails;
|
||||
private final List<AbstractFile> duplicates;
|
||||
private FileType fileType;
|
||||
|
||||
@ -54,6 +57,7 @@ class ResultFile {
|
||||
tagNames = new ArrayList<>();
|
||||
interestingSetNames = new ArrayList<>();
|
||||
objectDetectedNames = new ArrayList<>();
|
||||
thumbnails = new ArrayList<>();
|
||||
duplicates = new ArrayList<>();
|
||||
fileType = FileType.OTHER;
|
||||
}
|
||||
@ -198,6 +202,30 @@ class ResultFile {
|
||||
Collections.sort(interestingSetNames);
|
||||
}
|
||||
|
||||
private void createThumbnails(FileSearchData.FileType resultType) {
|
||||
if (resultType == FileType.IMAGE) {
|
||||
System.out.println("create single image thumbnail");
|
||||
thumbnails.add(ImageUtils.getThumbnail(abstractFile, ImageUtils.ICON_SIZE_MEDIUM));
|
||||
} else if (resultType == FileType.VIDEO) {
|
||||
thumbnails.add(ImageUtils.getThumbnail(abstractFile, ImageUtils.ICON_SIZE_LARGE));
|
||||
thumbnails.add(ImageUtils.getThumbnail(abstractFile, ImageUtils.ICON_SIZE_LARGE));
|
||||
thumbnails.add(ImageUtils.getThumbnail(abstractFile, ImageUtils.ICON_SIZE_LARGE));
|
||||
thumbnails.add(ImageUtils.getThumbnail(abstractFile, ImageUtils.ICON_SIZE_LARGE));
|
||||
} else {
|
||||
System.out.println("NOT IMAGE OR VIDEO: " + fileType.name());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
List<Image> getThumbnails(FileSearchData.FileType resultType) {
|
||||
if (thumbnails.isEmpty()) {
|
||||
System.out.println("IS EMPTY");
|
||||
createThumbnails(resultType);
|
||||
}
|
||||
System.out.println("THUMBNAILS GOT");
|
||||
return Collections.unmodifiableList(thumbnails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the interesting item set names for this file
|
||||
*
|
||||
@ -252,10 +280,10 @@ class ResultFile {
|
||||
if (this.getAbstractFile().getMd5Hash() == null
|
||||
|| HashUtility.isNoDataMd5(this.getAbstractFile().getMd5Hash())
|
||||
|| !HashUtility.isValidMd5Hash(this.getAbstractFile().getMd5Hash())) {
|
||||
return super.hashCode();
|
||||
return super.hashCode();
|
||||
} else {
|
||||
//if the file has a valid MD5 use the hashcode of the MD5 for deduping files with the same MD5
|
||||
return this.getAbstractFile().getMd5Hash().hashCode();
|
||||
return this.getAbstractFile().getMd5Hash().hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
@ -268,7 +296,7 @@ class ResultFile {
|
||||
|| !HashUtility.isValidMd5Hash(this.getAbstractFile().getMd5Hash())) {
|
||||
return super.equals(obj);
|
||||
} else {
|
||||
//if the file has a valid MD5 compare use the MD5 for equality check
|
||||
//if the file has a valid MD5 compare use the MD5 for equality check
|
||||
return this.getAbstractFile().getMd5Hash().equals(((ResultFile) obj).getAbstractFile().getMd5Hash());
|
||||
}
|
||||
}
|
||||
|
@ -17,15 +17,15 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="pagingPanel" max="32767" attributes="0"/>
|
||||
<Component id="resultsViewerPanel" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="pagingPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="resultsViewerPanel" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="jScrollPane1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -101,15 +101,6 @@
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="rolloverIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"/>
|
||||
</Property>
|
||||
@ -147,15 +138,6 @@
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[23, 23]"/>
|
||||
</Property>
|
||||
<Property name="rolloverIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"/>
|
||||
</Property>
|
||||
@ -234,9 +216,15 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="resultsViewerPanel">
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="resultsViewerPanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -19,7 +19,9 @@
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Image;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -32,6 +34,7 @@ import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerThumbnail;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
import org.sleuthkit.autopsy.directorytree.DataResultFilterNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Panel for displaying of file discovery results and handling the paging of
|
||||
@ -42,6 +45,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final DataResultViewerThumbnail thumbnailViewer;
|
||||
private final DataResultViewerTable tableViewer;
|
||||
private final VideoThumbnailViewer videoThumbnailViewer;
|
||||
private List<FileSearchFiltering.FileFilter> searchFilters;
|
||||
private FileSearch.AttributeType groupingAttribute;
|
||||
private FileGroup.GroupSortingAlgorithm groupSort;
|
||||
@ -62,6 +66,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
this.centralRepo = centralRepo;
|
||||
thumbnailViewer = new DataResultViewerThumbnail(explorerManager);
|
||||
tableViewer = new DataResultViewerTable(explorerManager);
|
||||
videoThumbnailViewer = new VideoThumbnailViewer();
|
||||
// Disable manual editing of page size spinner
|
||||
((JSpinner.DefaultEditor) pageSizeSpinner.getEditor()).getTextField().setEditable(false);
|
||||
}
|
||||
@ -79,17 +84,23 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
thumbnailViewer.resetComponent();
|
||||
resultsViewerPanel.remove(thumbnailViewer);
|
||||
resultsViewerPanel.remove(tableViewer);
|
||||
if (pageRetrievedEvent.getType() == FileSearchData.FileType.IMAGE || pageRetrievedEvent.getType() == FileSearchData.FileType.VIDEO) {
|
||||
if (pageRetrievedEvent.getType() == FileSearchData.FileType.IMAGE) {
|
||||
resultsViewerPanel.add(thumbnailViewer);
|
||||
if (pageRetrievedEvent.getSearchResults().size() > 0) {
|
||||
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new DiscoveryThumbnailChildren(pageRetrievedEvent.getSearchResults()))), true));
|
||||
List<AbstractFile> filesList = pageRetrievedEvent.getSearchResults().stream().map(file -> file.getAbstractFile()).collect(Collectors.toList());
|
||||
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(new AbstractNode(new DiscoveryThumbnailChildren(filesList))), true));
|
||||
} else {
|
||||
thumbnailViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true));
|
||||
}
|
||||
} else if (pageRetrievedEvent.getType() == FileSearchData.FileType.VIDEO) {
|
||||
populateVideoViewer(pageRetrievedEvent.getSearchResults());
|
||||
resultsViewerPanel.add(videoThumbnailViewer);
|
||||
|
||||
} else {
|
||||
resultsViewerPanel.add(tableViewer);
|
||||
if (pageRetrievedEvent.getSearchResults().size() > 0) {
|
||||
tableViewer.setNode(new TableFilterNode(new SearchNode(pageRetrievedEvent.getSearchResults()), true));
|
||||
List<AbstractFile> filesList = pageRetrievedEvent.getSearchResults().stream().map(file -> file.getAbstractFile()).collect(Collectors.toList());
|
||||
tableViewer.setNode(new TableFilterNode(new SearchNode(filesList), true));
|
||||
} else {
|
||||
tableViewer.setNode(new TableFilterNode(new DataResultFilterNode(Node.EMPTY), true));
|
||||
}
|
||||
@ -98,6 +109,19 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
});
|
||||
}
|
||||
|
||||
void populateVideoViewer(List<ResultFile> files) {
|
||||
System.out.println("POPULATE VIEWER");
|
||||
videoThumbnailViewer.clearViewer();
|
||||
for (ResultFile file : files) {
|
||||
System.out.println("NEW THREAD");
|
||||
new Thread(() -> {
|
||||
System.out.println("ON NEW THREAD");
|
||||
videoThumbnailViewer.addRow(file.getThumbnails(resultType), file.getAbstractFile().getParentPath());
|
||||
System.out.println("END NEW THREAD");
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe and respond to GroupSelectedEvents.
|
||||
*
|
||||
@ -168,6 +192,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
gotoPageLabel = new javax.swing.JLabel();
|
||||
gotoPageField = new javax.swing.JTextField();
|
||||
pageSizeLabel = new javax.swing.JLabel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
resultsViewerPanel = new javax.swing.JPanel();
|
||||
|
||||
pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
@ -177,9 +202,6 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
previousPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
|
||||
previousPageButton.setEnabled(false);
|
||||
previousPageButton.setFocusable(false);
|
||||
previousPageButton.setMaximumSize(new java.awt.Dimension(23, 23));
|
||||
previousPageButton.setMinimumSize(new java.awt.Dimension(23, 23));
|
||||
previousPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
previousPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
|
||||
previousPageButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@ -197,9 +219,6 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
|
||||
nextPageButton.setEnabled(false);
|
||||
nextPageButton.setFocusable(false);
|
||||
nextPageButton.setMaximumSize(new java.awt.Dimension(23, 23));
|
||||
nextPageButton.setMinimumSize(new java.awt.Dimension(23, 23));
|
||||
nextPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
|
||||
nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
|
||||
nextPageButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@ -244,9 +263,9 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(pageControlsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(previousPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(previousPageButton)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(nextPageButton)
|
||||
.addGap(18, 18, 18)
|
||||
.addComponent(gotoPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@ -262,9 +281,9 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
.addGroup(pagingPanelLayout.createSequentialGroup()
|
||||
.addGap(4, 4, 4)
|
||||
.addGroup(pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(nextPageButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(nextPageButton, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(previousPageButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(previousPageButton, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(pageControlsLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
@ -276,20 +295,21 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
);
|
||||
|
||||
resultsViewerPanel.setLayout(new java.awt.BorderLayout());
|
||||
jScrollPane1.setViewportView(resultsViewerPanel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pagingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(resultsViewerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(jScrollPane1)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(resultsViewerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(jScrollPane1))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
@ -368,6 +388,7 @@ public class ResultsPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JLabel currentPageLabel;
|
||||
private javax.swing.JTextField gotoPageField;
|
||||
private javax.swing.JLabel gotoPageLabel;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JButton nextPageButton;
|
||||
private javax.swing.JLabel pageControlsLabel;
|
||||
private javax.swing.JLabel pageSizeLabel;
|
||||
|
@ -135,7 +135,7 @@ class SearchResults {
|
||||
* @param groupName The name of the group. Can have the size appended.
|
||||
* @return the list of abstract files
|
||||
*/
|
||||
List<AbstractFile> getAbstractFilesInGroup(String groupName) {
|
||||
List<ResultFile> getAbstractFilesInGroup(String groupName) {
|
||||
if (groupName != null) {
|
||||
final String modifiedGroupName = groupName.replaceAll(" \\([0-9]+\\)$", "");
|
||||
|
||||
@ -152,8 +152,8 @@ class SearchResults {
|
||||
*
|
||||
* @return the grouped and sorted results
|
||||
*/
|
||||
LinkedHashMap<String, List<AbstractFile>> toLinkedHashMap() throws FileSearchException {
|
||||
LinkedHashMap<String, List<AbstractFile>> map = new LinkedHashMap<>();
|
||||
LinkedHashMap<String, List<ResultFile>> toLinkedHashMap() throws FileSearchException {
|
||||
LinkedHashMap<String, List<ResultFile>> map = new LinkedHashMap<>();
|
||||
|
||||
// Sort the groups and files
|
||||
sortGroupsAndFiles();
|
||||
|
61
Core/src/org/sleuthkit/autopsy/filequery/ThumbnailPanel.form
Normal file
61
Core/src/org/sleuthkit/autopsy/filequery/ThumbnailPanel.form
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
|
||||
<EtchetBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="imagePanel" pref="756" max="32767" attributes="0"/>
|
||||
<Component id="fileInfoLabel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="imagePanel" pref="125" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileInfoLabel" pref="8" max="32767" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="imagePanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="fileInfoLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/filequery/Bundle.properties" key="ThumbnailPanel.fileInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
92
Core/src/org/sleuthkit/autopsy/filequery/ThumbnailPanel.java
Normal file
92
Core/src/org/sleuthkit/autopsy/filequery/ThumbnailPanel.java
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Image;
|
||||
import java.util.List;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author wschaefer
|
||||
*/
|
||||
public class ThumbnailPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final int GAP_SIZE = 2;
|
||||
|
||||
/**
|
||||
* Creates new form ThumbnailPanel
|
||||
*/
|
||||
public ThumbnailPanel(List<Image> thumbnails, String fileInfo) {
|
||||
initComponents();
|
||||
fileInfoLabel.setText(fileInfo);
|
||||
addThumbnails(thumbnails);
|
||||
this.setFocusable(true);
|
||||
}
|
||||
|
||||
private void addThumbnails(List<Image> thumbnails) {
|
||||
GridBagConstraints gridBagConstraints = new GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
||||
imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(2, 0), new java.awt.Dimension(2, 0), new java.awt.Dimension(2, 32767)));
|
||||
gridBagConstraints.gridx++;
|
||||
for (Image image : thumbnails) {
|
||||
imagePanel.add(new JLabel(new ImageIcon(image)), gridBagConstraints);
|
||||
gridBagConstraints.gridx++;
|
||||
imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(2, 0), new java.awt.Dimension(2, 0), new java.awt.Dimension(2, 32767)));
|
||||
gridBagConstraints.gridx++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
imagePanel = new javax.swing.JPanel();
|
||||
fileInfoLabel = new javax.swing.JLabel();
|
||||
|
||||
setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
|
||||
imagePanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileInfoLabel, org.openide.util.NbBundle.getMessage(ThumbnailPanel.class, "ThumbnailPanel.fileInfoLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 756, Short.MAX_VALUE)
|
||||
.addComponent(fileInfoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(fileInfoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 8, Short.MAX_VALUE)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel fileInfoLabel;
|
||||
private javax.swing.JPanel imagePanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Form>
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.filequery;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Image;
|
||||
import java.util.List;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author wschaefer
|
||||
*/
|
||||
public class VideoThumbnailViewer extends javax.swing.JPanel {
|
||||
|
||||
private int nextRow = 0;
|
||||
|
||||
/**
|
||||
* Creates new form VideoThumbnailViewer
|
||||
*/
|
||||
public VideoThumbnailViewer() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
void clearViewer(){
|
||||
nextRow = 0;
|
||||
this.removeAll();
|
||||
}
|
||||
|
||||
void addRow(List<Image> thumbnails, String fileInfo) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
GridBagConstraints gridBagConstraints = new GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
|
||||
synchronized (this) {
|
||||
gridBagConstraints.gridy = nextRow;
|
||||
nextRow++;
|
||||
}
|
||||
this.add(new ThumbnailPanel(thumbnails, fileInfo), gridBagConstraints);
|
||||
System.out.println("ROW ADDED");
|
||||
revalidate();
|
||||
repaint();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user