diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/WhereUsedSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/WhereUsedSummary.java index ee6d2d6329..391205d5a3 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/WhereUsedSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/WhereUsedSummary.java @@ -230,6 +230,13 @@ public class WhereUsedSummary implements DefaultArtifactUpdateGovernor { this.provider = provider; this.logger = logger; } + + /** + * @return Returns all the geolocation artifact types. + */ + public List getGeoTypes() { + return GPS_ARTIFACT_TYPES; + } @Override public Set getArtifactTypeIdsForRefresh() { diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.form index 310b0563c4..4d0feedee4 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.form @@ -182,7 +182,11 @@ + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.java index e05109a46f..d1138c0f75 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/WhereUsedPanel.java @@ -20,21 +20,31 @@ package org.sleuthkit.autopsy.datasourcesummary.ui; import java.util.Arrays; import java.util.List; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.openide.util.NbBundle.Messages; +import org.openide.util.actions.CallableSystemAction; +import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.datasourcesummary.datamodel.WhereUsedSummary; import org.sleuthkit.autopsy.datasourcesummary.datamodel.WhereUsedSummary.CityCount; import org.sleuthkit.autopsy.datasourcesummary.datamodel.WhereUsedSummary.CityRecord; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; import org.sleuthkit.autopsy.datasourcesummary.uiutils.IngestRunningLabel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; +import org.sleuthkit.autopsy.geolocation.GeoFilter; +import org.sleuthkit.autopsy.geolocation.GeolocationTopComponent; +import org.sleuthkit.autopsy.geolocation.OpenGeolocationAction; +import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.DataSource; /** - * A tab shown in data source summary displaying information about a data source's geolocation data. + * A tab shown in data source summary displaying information about a data + * source's geolocation data. */ @Messages({ "WhereUsedPanel_cityColumn_title=Closest City", @@ -45,10 +55,11 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final String GPX_FACTORY = "org.python.proxies.GPX_Parser_Module$GPXParserFileIngestModuleFactory"; - private static final String GPX_NAME = "GPX Parser"; + private static final String GPX_NAME = "GPX Parser"; /** * Retrieves the city name to display from the record. + * * @param record The record for the city to display. * @return The display name (city, country). */ @@ -56,14 +67,14 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { if (record == null) { return null; } - + if (StringUtils.isBlank(record.getCountry())) { return record.getCityName(); } - + return String.format("%s, %s", record.getCityName(), record.getCountry()); } - + private static final ColumnModel CITY_COL = new ColumnModel<>( Bundle.WhereUsedPanel_cityColumn_title(), (cityCount) -> new DefaultCellModel(getCityName(cityCount.getCityRecord())), @@ -90,6 +101,8 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { private final IngestRunningLabel ingestRunningLabel = new IngestRunningLabel(); + private final WhereUsedSummary whereUsedData; + /** * Main constructor. */ @@ -99,25 +112,52 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { /** * Main constructor. - * @param geolocationData The GeolocationSummary instance to use. + * + * @param whereUsedData The GeolocationSummary instance to use. */ - public WhereUsedPanel(WhereUsedSummary geolocationData) { + public WhereUsedPanel(WhereUsedSummary whereUsedData) { + this.whereUsedData = whereUsedData; // set up data acquisition methods dataFetchComponents = Arrays.asList( new DataFetchWorker.DataFetchComponents<>( - (dataSource) -> geolocationData.getCityCounts(dataSource), - (result) -> showResultWithModuleCheck(cityCountsTable, result, GPX_FACTORY, GPX_NAME))); + (dataSource) -> whereUsedData.getCityCounts(dataSource), + (result) -> handleData(result))); initComponents(); } + private void handleData(DataFetchResult> result) { + if (result != null && result.getResultType() == DataFetchResult.ResultType.SUCCESS && CollectionUtils.isNotEmpty(result.getData())) { + viewInGeolocationBtn.setEnabled(true); + } + + showResultWithModuleCheck(cityCountsTable, result, GPX_FACTORY, GPX_NAME); + } + + private void openGeolocationWindow(DataSource dataSource) { + // open the window + OpenGeolocationAction geoAction = CallableSystemAction.get(OpenGeolocationAction.class); + if (geoAction != null) { + geoAction.performAction(); + } + + // set the filter + TopComponent topComponent = WindowManager.getDefault().findTopComponent(GeolocationTopComponent.class.getSimpleName()); + if (topComponent instanceof GeolocationTopComponent) { + GeolocationTopComponent geoComponent = (GeolocationTopComponent) topComponent; + geoComponent.fetchAndShowWaypoints(new GeoFilter(true, false, 0, Arrays.asList(dataSource), whereUsedData.getGeoTypes())); + } + } + @Override protected void fetchInformation(DataSource dataSource) { + viewInGeolocationBtn.setEnabled(false); fetchInformation(dataFetchComponents, dataSource); } @Override protected void onNewDataSource(DataSource dataSource) { + viewInGeolocationBtn.setEnabled(false); onNewDataSource(dataFetchComponents, tables, dataSource); } @@ -180,6 +220,12 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { mainContentPanel.add(filler3); org.openide.awt.Mnemonics.setLocalizedText(viewInGeolocationBtn, org.openide.util.NbBundle.getMessage(WhereUsedPanel.class, "WhereUsedPanel.viewInGeolocationBtn.text")); // NOI18N + viewInGeolocationBtn.setEnabled(false); + viewInGeolocationBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + viewInGeolocationBtnActionPerformed(evt); + } + }); mainContentPanel.add(viewInGeolocationBtn); filler5.setAlignmentX(0.0F); @@ -199,6 +245,10 @@ public class WhereUsedPanel extends BaseDataSourceSummaryPanel { ); }// //GEN-END:initComponents + private void viewInGeolocationBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInGeolocationBtnActionPerformed + openGeolocationWindow(getDataSource()); + }//GEN-LAST:event_viewInGeolocationBtnActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton viewInGeolocationBtn; diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java index fccdfacd29..1b74228ec0 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java @@ -39,14 +39,14 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter private static final Logger logger = Logger.getLogger(AbstractWaypointFetcher.class.getName()); - private final GeoFilterPanel.GeoFilter filters; + private final GeoFilter filters; /** * Constructs the Waypoint Runner * * @param filters */ - AbstractWaypointFetcher(GeoFilterPanel.GeoFilter filters) { + AbstractWaypointFetcher(GeoFilter filters) { this.filters = filters; } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java index df91b2963e..ad246210bc 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java @@ -356,98 +356,6 @@ class GeoFilterPanel extends javax.swing.JPanel { private javax.swing.JCheckBox showWaypointsWOTSCheckBox; // End of variables declaration//GEN-END:variables - /** - * Class to store the values of the Geolocation user set filter parameters - */ - final class GeoFilter { - - private final boolean showAll; - private final boolean showWithoutTimeStamp; - private final int mostRecentNumDays; - private final List dataSources; - private final List artifactTypes; - - /** - * Construct a Geolocation filter. showAll and mostRecentNumDays are - * exclusive filters, ie they cannot be used together. - * - * withoutTimeStamp is only applicable if mostRecentNumDays is true. - * - * When using the filters "most recent days" means to include waypoints - * for the numbers of days after the most recent waypoint, not the - * current date. - * - * @param showAll True if all waypoints should be shown - * @param withoutTimeStamp True to show waypoints without timeStamps, - * this filter is only applicable if mostRecentNumDays is true - * @param mostRecentNumDays Show Waypoint for the most recent given - * number of days. This parameter is ignored if showAll is true. - * @param dataSources A list of dataSources to filter waypoint for. - * @param artifactTypes A list of artifactTypes to filter waypoint for. - */ - GeoFilter(boolean showAll, boolean withoutTimeStamp, - int mostRecentNumDays, List dataSources, - List artifactTypes) { - this.showAll = showAll; - this.showWithoutTimeStamp = withoutTimeStamp; - this.mostRecentNumDays = mostRecentNumDays; - this.dataSources = dataSources; - this.artifactTypes = artifactTypes; - } - - /** - * Returns whether or not to show all waypoints. - * - * @return True if all waypoints should be shown. - */ - boolean showAllWaypoints() { - return showAll; - } - - /** - * Returns whether or not to include waypoints with time stamps. - * - * This filter is only applicable if "showAll" is true. - * - * @return True if waypoints with time stamps should be shown. - */ - boolean showWaypointsWithoutTimeStamp() { - return showWithoutTimeStamp; - } - - /** - * Returns the number of most recent days to show waypoints for. This - * value should be ignored if showAll is true. - * - * @return The number of most recent days to show waypoints for - */ - int getMostRecentNumDays() { - return mostRecentNumDays; - } - - /** - * Returns a list of data sources to filter the waypoints by, or null if - * all datasources should be include. - * - * @return A list of dataSources or null if all dataSources should be - * included. - */ - List getDataSources() { - return Collections.unmodifiableList(dataSources); - } - - /** - * Returns a list of artifact types to filter the waypoints by, or null - * if all types should be include. - * - * @return A list of artifactTypes or null if all artifactTypes should - * be included. - */ - List getArtifactTypes() { - return Collections.unmodifiableList(artifactTypes); - } - } - /** * Container for data sources and artifact types to be given as filter * options diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java index 31ef953fdc..2df34f1cb8 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java @@ -48,7 +48,6 @@ import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.autopsy.geolocation.GeoFilterPanel.GeoFilter; import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException; import org.sleuthkit.autopsy.ingest.IngestManager; import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED; @@ -295,6 +294,15 @@ public final class GeolocationTopComponent extends TopComponent { return; } + fetchAndShowWaypoints(filters); + } + + /** + * Loads and shows waypoints based on the filters. + * + * @param filters The filters to use. + */ + public void fetchAndShowWaypoints(GeoFilter filters) { setWaypointLoading(true); geoFilterPanel.setEnabled(false); @@ -491,8 +499,8 @@ public final class GeolocationTopComponent extends TopComponent { // End of variables declaration//GEN-END:variables /** - * Extends AbstractWaypointFetcher to handle the returning of - * the filters set of MapWaypoints. + * Extends AbstractWaypointFetcher to handle the returning of the filters + * set of MapWaypoints. */ @Messages({ "GeolocationTopComponent.WaypointFetcher.onErrorTitle=Error gathering GPS Track Data", @@ -507,13 +515,13 @@ public final class GeolocationTopComponent extends TopComponent { @Override void handleFilteredWaypointSet(Set mapWaypoints, List> tracks, boolean wasEntirelySuccessful) { addWaypointsToMap(mapWaypoints, tracks); - + // if there is an error, present to the user. if (!wasEntirelySuccessful) { - JOptionPane.showMessageDialog(GeolocationTopComponent.this, - Bundle.GeolocationTopComponent_WaypointFetcher_onErrorDescription(), - Bundle.GeolocationTopComponent_WaypointFetcher_onErrorTitle(), - JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(GeolocationTopComponent.this, + Bundle.GeolocationTopComponent_WaypointFetcher_onErrorDescription(), + Bundle.GeolocationTopComponent_WaypointFetcher_onErrorTitle(), + JOptionPane.ERROR_MESSAGE); } } }