diff --git a/Core/build.xml b/Core/build.xml index 5d91ade7e1..df747ff257 100644 --- a/Core/build.xml +++ b/Core/build.xml @@ -72,6 +72,9 @@ + + + diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 22af0f87c8..9db5951f69 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -2,8 +2,15 @@ file.reference.activemq-all-5.11.1.jar=release/modules/ext/activemq-all-5.11.1.j file.reference.apache-mime4j-core-0.8.2.jar=release\\modules\\ext\\apache-mime4j-core-0.8.2.jar file.reference.apache-mime4j-dom-0.8.2.jar=release\\modules\\ext\\apache-mime4j-dom-0.8.2.jar file.reference.asm-7.0.jar=release\\modules\\ext\\asm-7.0.jar +file.reference.batik-awt-util-1.6.jar=release/modules/ext/batik-awt-util-1.6.jar +file.reference.batik-dom-1.6.jar=release/modules/ext/batik-dom-1.6.jar +file.reference.batik-svg-dom-1.6.jar=release/modules/ext/batik-svg-dom-1.6.jar +file.reference.batik-svggen-1.6.jar=release/modules/ext/batik-svggen-1.6.jar +file.reference.batik-util-1.6.jar=release/modules/ext/batik-util-1.6.jar +file.reference.batik-xml-1.6.jar=release/modules/ext/batik-xml-1.6.jar file.reference.bcmail-jdk15on-1.60.jar=release\\modules\\ext\\bcmail-jdk15on-1.60.jar file.reference.bcpkix-jdk15on-1.60.jar=release\\modules\\ext\\bcpkix-jdk15on-1.60.jar +file.reference.bcprov-ext-jdk15on-1.54.jar=release/modules/ext/bcprov-ext-jdk15on-1.54.jar file.reference.bcprov-jdk15on-1.60.jar=release\\modules\\ext\\bcprov-jdk15on-1.60.jar file.reference.boilerpipe-1.1.0.jar=release\\modules\\ext\\boilerpipe-1.1.0.jar file.reference.c3p0-0.9.5.jar=release/modules/ext/c3p0-0.9.5.jar @@ -17,14 +24,17 @@ file.reference.commons-io-2.6.jar=release\\modules\\ext\\commons-io-2.6.jar file.reference.commons-lang3-3.8.1.jar=release\\modules\\ext\\commons-lang3-3.8.1.jar file.reference.commons-pool2-2.4.2.jar=release/modules/ext/commons-pool2-2.4.2.jar file.reference.cxf-rt-rs-client-3.3.0.jar=release\\modules\\ext\\cxf-rt-rs-client-3.3.0.jar +file.reference.DatCon.jar=release/modules/ext/DatCon.jar file.reference.dec-0.1.2.jar=release\\modules\\ext\\dec-0.1.2.jar -file.reference.decodetect-core-0.3.jar=release\\modules\\ext\\decodetect-core-0.3.jar +file.reference.decodetect-core-0.3.jar=release/modules/ext/decodetect-core-0.3.jar file.reference.fontbox-2.0.13.jar=release\\modules\\ext\\fontbox-2.0.13.jar file.reference.geoapi-3.0.1.jar=release\\modules\\ext\\geoapi-3.0.1.jar file.reference.grib-4.5.5.jar=release\\modules\\ext\\grib-4.5.5.jar file.reference.httpclient-4.5.6.jar=release\\modules\\ext\\httpclient-4.5.6.jar file.reference.httpmime-4.5.6.jar=release\\modules\\ext\\httpmime-4.5.6.jar file.reference.httpservices-4.5.5.jar=release\\modules\\ext\\httpservices-4.5.5.jar +file.reference.icepdf-core-6.2.2.jar=release/modules/ext/icepdf-core-6.2.2.jar +file.reference.icepdf-viewer-6.2.2.jar=release/modules/ext/icepdf-viewer-6.2.2.jar file.reference.isoparser-1.1.22.jar=release\\modules\\ext\\isoparser-1.1.22.jar file.reference.jackcess-2.2.0.jar=release\\modules\\ext\\jackcess-2.2.0.jar file.reference.jackcess-encrypt-2.1.4.jar=release\\modules\\ext\\jackcess-encrypt-2.1.4.jar @@ -32,6 +42,8 @@ file.reference.jackson-annotations-2.9.7.jar=release\\modules\\ext\\jackson-anno file.reference.jackson-core-2.9.7.jar=release\\modules\\ext\\jackson-core-2.9.7.jar file.reference.jackson-databind-2.9.7.jar=release\\modules\\ext\\jackson-databind-2.9.7.jar file.reference.jai-imageio-core-1.4.0.jar=release\\modules\\ext\\jai-imageio-core-1.4.0.jar +file.reference.jai_core-1.1.3.jar=release/modules/ext/jai_core-1.1.3.jar +file.reference.jai_imageio-1.1.jar=release/modules/ext/jai_imageio-1.1.jar file.reference.java-libpst-0.8.1.jar=release\\modules\\ext\\java-libpst-0.8.1.jar file.reference.javax.activation-1.2.0.jar=release\\modules\\ext\\javax.activation-1.2.0.jar file.reference.javax.annotation-api-1.3.2.jar=release\\modules\\ext\\javax.annotation-api-1.3.2.jar @@ -50,7 +62,7 @@ file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar file.reference.juniversalchardet-1.0.3.jar=release\\modules\\ext\\juniversalchardet-1.0.3.jar file.reference.junrar-2.0.0.jar=release\\modules\\ext\\junrar-2.0.0.jar -file.reference.jutf7-1.0.0.jar=release\\modules\\ext\\jutf7-1.0.0.jar +file.reference.jutf7-1.0.0.jar=release/modules/ext/jutf7-1.0.0.jar file.reference.jxmapviewer2-2.4.jar=release/modules/ext/jxmapviewer2-2.4.jar file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar file.reference.libphonenumber-3.5.jar=release/modules/ext/libphonenumber-3.5.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 79c518eeaa..bf917fc039 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -355,6 +355,14 @@ ext/commons-lang3-3.8.1.jar release\modules\ext\commons-lang3-3.8.1.jar + + ext/batik-xml-1.6.jar + release/modules/ext/batik-xml-1.6.jar + + + ext/jai_core-1.1.3.jar + release/modules/ext/jai_core-1.1.3.jar + ext/gax-grpc-1.44.0.jar release/modules/ext/gax-grpc-1.44.0.jar @@ -371,6 +379,10 @@ ext/opencensus-api-0.19.2.jar release/modules/ext/opencensus-api-0.19.2.jar + + ext/batik-svg-dom-1.6.jar + release/modules/ext/batik-svg-dom-1.6.jar + ext/gax-httpjson-0.61.0.jar release/modules/ext/gax-httpjson-0.61.0.jar @@ -479,6 +491,10 @@ ext/xmpcore-5.1.3.jar release/modules/ext/xmpcore-5.1.3.jar + + ext/batik-util-1.6.jar + release/modules/ext/batik-util-1.6.jar + ext/javax.activation-1.2.0.jar release\modules\ext\javax.activation-1.2.0.jar @@ -499,6 +515,10 @@ ext/jgraphx-4.1.0.jar release/modules/ext/jgraphx-4.1.0.jar + + ext/DatCon.jar + release/modules/ext/DatCon.jar + ext/java-libpst-0.8.1.jar release\modules\ext\java-libpst-0.8.1.jar @@ -535,10 +555,6 @@ ext/google-http-client-1.29.0.jar release/modules/ext/google-http-client-1.29.0.jar - - ext/sleuthkit-postgresql-4.9.0.jar - release/modules/ext/sleuthkit-postgresql-4.9.0.jar - ext/bcpkix-jdk15on-1.60.jar release\modules\ext\bcpkix-jdk15on-1.60.jar @@ -551,6 +567,10 @@ ext/slf4j-api-1.7.25.jar release\modules\ext\slf4j-api-1.7.25.jar + + ext/bcprov-ext-jdk15on-1.54.jar + release/modules/ext/bcprov-ext-jdk15on-1.54.jar + ext/google-cloud-core-1.70.0.jar release/modules/ext/google-cloud-core-1.70.0.jar @@ -619,6 +639,14 @@ ext/commons-validator-1.6.jar release/modules/ext/commons-validator-1.6.jar + + ext/sleuthkit-postgresql-4.9.0.jar + release/modules/ext/sleuthkit-postgresql-4.9.0.jar + + + ext/decodetect-core-0.3.jar + release/modules/ext/decodetect-core-0.3.jar + ext/jbig2-imageio-3.0.2.jar release\modules\ext\jbig2-imageio-3.0.2.jar @@ -667,6 +695,10 @@ ext/SparseBitSet-1.1.jar release/modules/ext/SparseBitSet-1.1.jar + + ext/batik-svggen-1.6.jar + release/modules/ext/batik-svggen-1.6.jar + ext/c3p0-0.9.5.jar release/modules/ext/c3p0-0.9.5.jar @@ -735,6 +767,10 @@ ext/postgresql-9.4.1211.jre7.jar release/modules/ext/postgresql-9.4.1211.jre7.jar + + ext/jai_imageio-1.1.jar + release/modules/ext/jai_imageio-1.1.jar + ext/httpclient-4.5.6.jar release\modules\ext\httpclient-4.5.6.jar @@ -747,6 +783,10 @@ ext/fontbox-2.0.13.jar release\modules\ext\fontbox-2.0.13.jar + + ext/icepdf-core-6.2.2.jar + release/modules/ext/icepdf-core-6.2.2.jar + ext/activemq-all-5.11.1.jar release/modules/ext/activemq-all-5.11.1.jar @@ -763,6 +803,10 @@ ext/dec-0.1.2.jar release\modules\ext\dec-0.1.2.jar + + ext/batik-dom-1.6.jar + release/modules/ext/batik-dom-1.6.jar + ext/google-http-client-jackson2-1.29.0.jar release/modules/ext/google-http-client-jackson2-1.29.0.jar @@ -779,6 +823,14 @@ ext/sevenzipjbinding-AllPlatforms.jar release/modules/ext/sevenzipjbinding-AllPlatforms.jar + + ext/jutf7-1.0.0.jar + release/modules/ext/jutf7-1.0.0.jar + + + ext/batik-awt-util-1.6.jar + release/modules/ext/batik-awt-util-1.6.jar + ext/google-api-services-translate-v2-rev20170525-1.27.0.jar release/modules/ext/google-api-services-translate-v2-rev20170525-1.27.0.jar @@ -787,6 +839,10 @@ ext/webp-imageio-sejda-0.1.0.jar release/modules/ext/webp-imageio-sejda-0.1.0.jar + + ext/icepdf-viewer-6.2.2.jar + release/modules/ext/icepdf-viewer-6.2.2.jar + ext/bcmail-jdk15on-1.60.jar release\modules\ext\bcmail-jdk15on-1.60.jar @@ -795,18 +851,6 @@ ext/vorbis-java-tika-0.8.jar release\modules\ext\vorbis-java-tika-0.8.jar - - ext/decodetect-core-0.3.jar - release/modules/ext/decodetect-core-0.3.jar - - - ext/jutf7-1.0.0.jar - release/modules/ext/jutf7-1.0.0.jar - - - ext/DatCon.jar - release/modules/ext/DatCon.jar - diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index b70845e3df..5a703a4ea9 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.casemodule; import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils; import com.google.common.annotations.Beta; import com.google.common.eventbus.Subscribe; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData; import java.awt.Frame; import java.awt.event.ActionEvent; @@ -125,6 +126,7 @@ import org.sleuthkit.datamodel.CaseDbConnectionInfo; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Report; import org.sleuthkit.datamodel.SleuthkitCase; @@ -156,6 +158,9 @@ public class Case { private static final Logger logger = Logger.getLogger(Case.class.getName()); private static final AutopsyEventPublisher eventPublisher = new AutopsyEventPublisher(); private static final Object caseActionSerializationLock = new Object(); + private static Future backgroundOpenFileSystemsFuture = null; + private static final ExecutorService openFileSystemsExecutor + = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("case-open-file-systems-%d").build()); private static volatile Frame mainFrame; private static volatile Case currentCase; private final CaseMetadata metadata; @@ -1979,6 +1984,8 @@ public class Case { openAppServiceCaseResources(progressIndicator); checkForCancellation(); openCommunicationChannels(progressIndicator); + checkForCancellation(); + openFileSystemsInBackground(); return null; } catch (CaseActionException ex) { @@ -1997,6 +2004,141 @@ public class Case { } } + /** + * Starts a background task that reads a sector from each file system of + * each image of a case to do an eager open of the filesystems in the case. + * If this method is called before another background file system read has + * finished the earlier one will be cancelled. + * + * @throws CaseActionCancelledException Exception thrown if task is + * cancelled. + */ + @Messages({ + "# {0} - case", "Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...", + "# {0} - image", "Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..." + }) + private void openFileSystemsInBackground() { + if (backgroundOpenFileSystemsFuture != null && !backgroundOpenFileSystemsFuture.isDone()) { + backgroundOpenFileSystemsFuture.cancel(true); + } + + BackgroundOpenFileSystemsTask backgroundTask = new BackgroundOpenFileSystemsTask(this.caseDb, new LoggingProgressIndicator()); + backgroundOpenFileSystemsFuture = openFileSystemsExecutor.submit(backgroundTask); + } + + /** + * This task opens all the filesystems of all images in the case in the + * background. It also responds to cancellation events. + */ + private static class BackgroundOpenFileSystemsTask implements Runnable { + + private final SleuthkitCase tskCase; + private final String caseName; + private final ProgressIndicator progressIndicator; + + /** + * Main constructor for the BackgroundOpenFileSystemsTask. + * + * @param tskCase The case database to query for filesystems + * to open. + * @param progressIndicator The progress indicator for file systems + * opened. + */ + BackgroundOpenFileSystemsTask(SleuthkitCase tskCase, ProgressIndicator progressIndicator) { + this.tskCase = tskCase; + this.progressIndicator = progressIndicator; + caseName = (this.tskCase != null) ? this.tskCase.getDatabaseName() : ""; + } + + /** + * Checks if thread has been cancelled and throws an + * InterruptedException if it has. + * + * @throws InterruptedException The exception thrown if the operation + * has been cancelled. + */ + private void checkIfCancelled() throws InterruptedException { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + } + + /** + * Retrieves all images present in the sleuthkit case. + * + * @return All images present in the sleuthkit case. + */ + private List getImages() { + progressIndicator.progress(Bundle.Case_openFileSystems_retrievingImages(caseName)); + try { + return this.tskCase.getImages(); + } catch (TskCoreException ex) { + logger.log( + Level.SEVERE, + String.format("Could not obtain images while opening case: %s.", caseName), + ex); + + return null; + } + } + + /** + * Opens all file systems in the list of images provided. + * + * @param images The images whose file systems will be opened. + * + * @throws CaseActionCancelledException The exception thrown in the + * event that the operation is + * cancelled prior to completion. + */ + private void openFileSystems(List images) throws InterruptedException { + byte[] tempBuff = new byte[512]; + + for (Image image : images) { + String imageStr = image.getName(); + + progressIndicator.progress(Bundle.Case_openFileSystems_openingImage(imageStr)); + + Collection fileSystems = this.tskCase.getFileSystems(image); + checkIfCancelled(); + for (FileSystem fileSystem : fileSystems) { + try { + fileSystem.read(tempBuff, 0, 512); + } catch (TskCoreException ex) { + String fileSysStr = fileSystem.getName(); + + logger.log( + Level.WARNING, + String.format("Could not open filesystem: %s in image: %s for case: %s.", fileSysStr, imageStr, caseName), + ex); + } + + checkIfCancelled(); + } + + } + } + + @Override + public void run() { + try { + checkIfCancelled(); + List images = getImages(); + if (images == null) { + return; + } + + checkIfCancelled(); + openFileSystems(images); + } catch (InterruptedException ex) { + logger.log( + Level.INFO, + String.format("Background operation opening all file systems in %s has been cancelled.", caseName)); + } + } + + } + /** * A case action (interface CaseAction) that opens a case, deletes * a data source from the case, and closes the case. diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.form index 47481f8bdd..0d49bf2241 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.form @@ -312,67 +312,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -380,15 +320,20 @@ - + - + + + + + + @@ -402,6 +347,11 @@ + + + + + @@ -409,15 +359,20 @@ - + - + + + + + + @@ -428,22 +383,37 @@ - + - + + + + + + + + + + + + + + + + @@ -451,15 +421,20 @@ - + - + + + + + + @@ -467,17 +442,27 @@ - + - + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java index b5706027a3..45a0b49242 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/OptionalCasePropertiesPanel.java @@ -19,8 +19,10 @@ package org.sleuthkit.autopsy.casemodule; import java.awt.Cursor; +import java.awt.Dialog; import java.util.logging.Level; import javax.swing.JComboBox; +import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; @@ -227,6 +229,7 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; casePanel = new javax.swing.JPanel(); caseNumberLabel = new javax.swing.JLabel(); @@ -378,95 +381,114 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel { ); orgainizationPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.orgainizationPanel.border.title"))); // NOI18N + orgainizationPanel.setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactPhoneLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactPhoneLabel.text")); // NOI18N - lbPointOfContactPhoneLabel.setMaximumSize(new java.awt.Dimension(82, 14)); + lbPointOfContactPhoneLabel.setMaximumSize(new java.awt.Dimension(182, 14)); lbPointOfContactPhoneLabel.setMinimumSize(new java.awt.Dimension(82, 14)); - lbPointOfContactPhoneLabel.setPreferredSize(new java.awt.Dimension(82, 14)); + lbPointOfContactPhoneLabel.setPreferredSize(new java.awt.Dimension(120, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 12, 0, 0); + orgainizationPanel.add(lbPointOfContactPhoneLabel, gridBagConstraints); comboBoxOrgName.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { comboBoxOrgNameActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(8, 18, 0, 0); + orgainizationPanel.add(comboBoxOrgName, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactNameLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactNameLabel.text")); // NOI18N - lbPointOfContactNameLabel.setMaximumSize(new java.awt.Dimension(82, 14)); + lbPointOfContactNameLabel.setMaximumSize(new java.awt.Dimension(182, 14)); lbPointOfContactNameLabel.setMinimumSize(new java.awt.Dimension(82, 14)); - lbPointOfContactNameLabel.setPreferredSize(new java.awt.Dimension(82, 14)); + lbPointOfContactNameLabel.setPreferredSize(new java.awt.Dimension(120, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(13, 12, 0, 5); + orgainizationPanel.add(lbPointOfContactNameLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(bnNewOrganization, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.bnNewOrganization.text")); // NOI18N bnNewOrganization.setMargin(new java.awt.Insets(2, 6, 2, 6)); - bnNewOrganization.setMaximumSize(new java.awt.Dimension(123, 23)); + bnNewOrganization.setMaximumSize(new java.awt.Dimension(160, 23)); bnNewOrganization.setMinimumSize(new java.awt.Dimension(123, 23)); - bnNewOrganization.setPreferredSize(new java.awt.Dimension(123, 23)); + bnNewOrganization.setPreferredSize(new java.awt.Dimension(140, 23)); bnNewOrganization.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnNewOrganizationActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(8, 12, 0, 18); + orgainizationPanel.add(bnNewOrganization, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 4, 13, 18); + orgainizationPanel.add(lbPointOfContactEmailText, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(13, 4, 0, 18); + orgainizationPanel.add(lbPointOfContactNameText, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(lbOrganizationNameLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbOrganizationNameLabel.text")); // NOI18N - lbOrganizationNameLabel.setMaximumSize(new java.awt.Dimension(189, 14)); + lbOrganizationNameLabel.setMaximumSize(new java.awt.Dimension(300, 14)); lbOrganizationNameLabel.setMinimumSize(new java.awt.Dimension(189, 14)); - lbOrganizationNameLabel.setPreferredSize(new java.awt.Dimension(189, 14)); + lbOrganizationNameLabel.setPreferredSize(new java.awt.Dimension(220, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); + orgainizationPanel.add(lbOrganizationNameLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactEmailLabel, org.openide.util.NbBundle.getMessage(OptionalCasePropertiesPanel.class, "OptionalCasePropertiesPanel.lbPointOfContactEmailLabel.text")); // NOI18N - lbPointOfContactEmailLabel.setMaximumSize(new java.awt.Dimension(82, 14)); + lbPointOfContactEmailLabel.setMaximumSize(new java.awt.Dimension(182, 14)); lbPointOfContactEmailLabel.setMinimumSize(new java.awt.Dimension(82, 14)); - lbPointOfContactEmailLabel.setPreferredSize(new java.awt.Dimension(82, 14)); - - javax.swing.GroupLayout orgainizationPanelLayout = new javax.swing.GroupLayout(orgainizationPanel); - orgainizationPanel.setLayout(orgainizationPanelLayout); - orgainizationPanelLayout.setHorizontalGroup( - orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(orgainizationPanelLayout.createSequentialGroup() - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(orgainizationPanelLayout.createSequentialGroup() - .addGap(106, 106, 106) - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGroup(orgainizationPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE) - .addGap(18, 18, 18) - .addComponent(comboBoxOrgName, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnNewOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) - ); - - orgainizationPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {lbPointOfContactEmailLabel, lbPointOfContactNameLabel, lbPointOfContactPhoneLabel}); - - orgainizationPanelLayout.setVerticalGroup( - orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(orgainizationPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(comboBoxOrgName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnNewOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(orgainizationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(6, 6, 6)) - ); + lbPointOfContactEmailLabel.setPreferredSize(new java.awt.Dimension(120, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 12, 13, 0); + orgainizationPanel.add(lbPointOfContactEmailLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 4, 0, 18); + orgainizationPanel.add(lbPointOfContactPhoneText, gridBagConstraints); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -516,7 +538,7 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel { }//GEN-LAST:event_comboBoxOrgNameActionPerformed private void bnNewOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnNewOrganizationActionPerformed - ManageOrganizationsDialog dialog = new ManageOrganizationsDialog(); + ManageOrganizationsDialog dialog = new ManageOrganizationsDialog((Dialog) SwingUtilities.getWindowAncestor(this)); // update the combobox options and org data fields loadOrganizationData(); if (dialog.isChanged()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form index fd1b0b81b1..f8ceec50e7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.form @@ -67,7 +67,7 @@ - + @@ -87,16 +87,10 @@ - - - - - - - - + + - + @@ -104,45 +98,15 @@ - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - @@ -292,6 +256,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java index 1429a60312..56922c7bfb 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/contentviewer/DataContentViewerOtherCases.java @@ -958,6 +958,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; rightClickPopupMenu = new javax.swing.JPopupMenu(); exportToCSVMenuItem = new javax.swing.JMenuItem(); @@ -965,9 +966,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi showCommonalityMenuItem = new javax.swing.JMenuItem(); CSVFileChooser = new javax.swing.JFileChooser(); tableContainerPanel = new javax.swing.JPanel(); - earliestCaseLabel = new javax.swing.JLabel(); - earliestCaseDate = new javax.swing.JLabel(); - foundInLabel = new javax.swing.JLabel(); tablesViewerSplitPane = new javax.swing.JSplitPane(); caseDatasourceFileSplitPane = new javax.swing.JSplitPane(); caseDatasourceSplitPane = new javax.swing.JSplitPane(); @@ -978,6 +976,11 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi filesTableScrollPane = new javax.swing.JScrollPane(); filesTable = new javax.swing.JTable(); detailsPanelScrollPane = new javax.swing.JScrollPane(); + jPanel1 = new javax.swing.JPanel(); + foundInLabel = new javax.swing.JLabel(); + earliestCaseDate = new javax.swing.JLabel(); + earliestCaseLabel = new javax.swing.JLabel(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() { public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) { @@ -1005,13 +1008,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi tableContainerPanel.setPreferredSize(new java.awt.Dimension(600, 63)); tableContainerPanel.setRequestFocusEnabled(false); - org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.text")); // NOI18N - earliestCaseLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.toolTipText")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseDate.text")); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(foundInLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.foundInLabel.text")); // NOI18N - tablesViewerSplitPane.setDividerLocation(450); tablesViewerSplitPane.setResizeWeight(0.75); @@ -1057,33 +1053,64 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi detailsPanelScrollPane.setPreferredSize(new java.awt.Dimension(300, 100)); tablesViewerSplitPane.setRightComponent(detailsPanelScrollPane); + jPanel1.setPreferredSize(new java.awt.Dimension(576, 22)); + jPanel1.setLayout(new java.awt.GridBagLayout()); + + foundInLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + org.openide.awt.Mnemonics.setLocalizedText(foundInLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.foundInLabel.text")); // NOI18N + foundInLabel.setPreferredSize(new java.awt.Dimension(400, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; + gridBagConstraints.insets = new java.awt.Insets(2, 2, 0, 0); + jPanel1.add(foundInLabel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseDate.text")); // NOI18N + earliestCaseDate.setMaximumSize(new java.awt.Dimension(200, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 7, 0, 0); + jPanel1.add(earliestCaseDate, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(earliestCaseLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.text")); // NOI18N + earliestCaseLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseLabel.toolTipText")); // NOI18N + earliestCaseLabel.setMaximumSize(new java.awt.Dimension(260, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + jPanel1.add(earliestCaseLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 0.1; + jPanel1.add(filler1, gridBagConstraints); + javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel); tableContainerPanel.setLayout(tableContainerPanelLayout); tableContainerPanelLayout.setHorizontalGroup( tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(tableContainerPanelLayout.createSequentialGroup() .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(tableContainerPanelLayout.createSequentialGroup() - .addComponent(earliestCaseLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(earliestCaseDate, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(foundInLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 990, Short.MAX_VALUE)) + .addComponent(tablesViewerSplitPane) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); tableContainerPanelLayout.setVerticalGroup( tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(tableContainerPanelLayout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE) + .addComponent(tablesViewerSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(earliestCaseLabel) - .addComponent(earliestCaseDate)) - .addComponent(foundInLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(12, 12, 12)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -1095,7 +1122,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE) + .addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE) .addGap(0, 0, 0)) ); }// //GEN-END:initComponents @@ -1128,7 +1155,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi private javax.swing.JMenuItem exportToCSVMenuItem; private javax.swing.JTable filesTable; private javax.swing.JScrollPane filesTableScrollPane; + private javax.swing.Box.Filler filler1; private javax.swing.JLabel foundInLabel; + private javax.swing.JPanel jPanel1; private javax.swing.JPopupMenu rightClickPopupMenu; private javax.swing.JMenuItem showCaseDetailsMenuItem; private javax.swing.JMenuItem showCommonalityMenuItem; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 3fab7af47f..b0f288673b 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -30,7 +30,8 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; /** - * This class contains business logic for saving and validating settings for central repository. + * This class contains business logic for saving and validating settings for + * central repository. */ public class CentralRepoDbManager { @@ -42,35 +43,40 @@ public class CentralRepoDbManager { private static final String DISABLED_DUE_TO_FAILURE_KEY = "disabledDueToFailure"; private static volatile CentralRepoDbChoice savedChoice = null; - + private static final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(CentralRepoDbManager.class); - + private static final Object dbChoiceLock = new Object(); private static final Object disabledDueToFailureLock = new Object(); - - - + /** - * This saves the currently selected database choice and clears any disabledDueToFailure flag. - * @param choice The choice to save. - * @return The newly saved choice. + * This saves the currently selected database choice and clears any + * disabledDueToFailure flag. + * + * @param choice The choice to save. + * + * @return The newly saved choice. */ public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice) { return saveDbChoice(choice, true); } - + /** * This saves the currently selected database choice. - * @param choice The choice to save. - * @param clearDisabledDueToError Whether or not to clear the 'disabledDueToFailure' settings key. - * @return The newly saved choice. + * + * @param choice The choice to save. + * @param clearDisabledDueToError Whether or not to clear the + * 'disabledDueToFailure' settings key. + * + * @return The newly saved choice. */ public static CentralRepoDbChoice saveDbChoice(CentralRepoDbChoice choice, boolean clearDisabledDueToError) { - synchronized(dbChoiceLock) { + synchronized (dbChoiceLock) { // clear disabling due to a failure - if (clearDisabledDueToError) + if (clearDisabledDueToError) { setDisabledDueToFailure(false); - + } + // change the settings CentralRepoDbChoice newChoice = (choice == null) ? CentralRepoDbChoice.DISABLED : choice; CentralRepoDbChoice oldChoice = savedChoice; @@ -81,55 +87,61 @@ public class CentralRepoDbManager { } } - + /** - * This method indicates whether or not 'PostgreSQL using multi-user settings' is a valid option. - * @return True if 'PostgreSQL using multi-user settings' is valid. + * This method indicates whether or not 'PostgreSQL using multi-user + * settings' is a valid option. + * + * @return True if 'PostgreSQL using multi-user settings' is valid. */ public static boolean isPostgresMultiuserAllowed() { // if multi user mode is not enabled, then this cannot be used - if (!UserPreferences.getIsMultiUserModeEnabled()) + if (!UserPreferences.getIsMultiUserModeEnabled()) { return false; - + } // also validate the connection as well - PostgresCentralRepoSettings multiUserSettings = - new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); - + PostgresCentralRepoSettings multiUserSettings + = new PostgresCentralRepoSettings(PostgresSettingsLoader.MULTIUSER_SETTINGS_LOADER); + return multiUserSettings.testStatus() == DatabaseTestResult.TESTED_OK; } - /** - * This method loads the selectedPlatform boolean from the config file if it is set. + * This method loads the selectedPlatform boolean from the config file if it + * is set. */ public static CentralRepoDbChoice getSavedDbChoice() { - synchronized(dbChoiceLock) { + synchronized (dbChoiceLock) { if (savedChoice == null) { String selectedPlatformString = ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DB_SELECTED_PLATFORM_KEY); // NON-NLS savedChoice = fromKey(selectedPlatformString); } - return savedChoice; + return savedChoice; } } - + /** - * This method disables the central repository and indicates through a flag that this was due to a failure during database setup. - * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. + * This method disables the central repository and indicates through a flag + * that this was due to a failure during database setup. This is used when + * re-enabling multi-user as a flag to determine whether or not CR should be + * re-enabled. */ public static void disableDueToFailure() { CentralRepoDbUtil.setUseCentralRepo(false); setDisabledDueToFailure(true); } - + /** - * This method sets whether or not the repository has been disabled due to a database setup issue; - * This is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - * - * @param disabledDueToFailure Whether or not the repository has been disabled due to a database setup issue. + * This method sets whether or not the repository has been disabled due to a + * database setup issue; This is used when re-enabling multi-user as a flag + * to determine whether or not CR should be re-enabled. + * + * @param disabledDueToFailure Whether or not the repository has been + * disabled due to a database setup issue. */ private static void setDisabledDueToFailure(boolean disabledDueToFailure) { - synchronized(disabledDueToFailureLock) { + synchronized (disabledDueToFailureLock) { boolean oldValue = isDisabledDueToFailure(); ModuleSettings.setConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY, Boolean.toString(disabledDueToFailure)); propertyChangeSupport.firePropertyChange("disabledDueToFailure", oldValue, disabledDueToFailure); @@ -137,36 +149,38 @@ public class CentralRepoDbManager { } /** - * This method retrieves setting whether or not the repository has been disabled due to a database setup issue; - * this is used when re-enabling multi-user as a flag to determine whether or not CR should be re-enabled. - * - * @return Whether or not the repository has been disabled due to a database setup issue. + * This method retrieves setting whether or not the repository has been + * disabled due to a database setup issue; this is used when re-enabling + * multi-user as a flag to determine whether or not CR should be re-enabled. + * + * @return Whether or not the repository has been disabled due to a database + * setup issue. */ public static boolean isDisabledDueToFailure() { - synchronized(disabledDueToFailureLock) { + synchronized (disabledDueToFailureLock) { return Boolean.toString(true).equals(ModuleSettings.getConfigSetting(CENTRAL_REPOSITORY_SETTINGS_KEY, DISABLED_DUE_TO_FAILURE_KEY)); } } /** - * This method adds a property change listener. - * NOTE: currently only listening for changes in currently saved db choice and disabling due to failure. - * - * @param listener The listener for the event. + * This method adds a property change listener. NOTE: currently only + * listening for changes in currently saved db choice and disabling due to + * failure. + * + * @param listener The listener for the event. */ public static void addPropertyChangeListener(PropertyChangeListener listener) { - propertyChangeSupport.addPropertyChangeListener(listener); - } + propertyChangeSupport.addPropertyChangeListener(listener); + } /** * This method removes a propert change listener. - * @param listener The listener to remove. + * + * @param listener The listener to remove. */ - public static void removePropertyChangeListener(PropertyChangeListener listener) { - propertyChangeSupport.removePropertyChangeListener(listener); - } - - + public static void removePropertyChangeListener(PropertyChangeListener listener) { + propertyChangeSupport.removePropertyChangeListener(listener); + } private static CentralRepoDbChoice fromKey(String keyName) { for (CentralRepoDbChoice dbChoice : CentralRepoDbChoice.values()) { @@ -178,12 +192,11 @@ public class CentralRepoDbManager { return CentralRepoDbChoice.DISABLED; } - - /** * This method obtains the database connectivity for central repository. * * @return The CentralRepository object that will be used for connection. + * * @throws CentralRepoException */ private static CentralRepository obtainCentralRepository() throws CentralRepoException { @@ -203,8 +216,10 @@ public class CentralRepoDbManager { /** * This method obtains a central repository lock. * - * @param db The database connection. - * @return The lock if acquired. + * @param db The database connection. + * + * @return The lock if acquired. + * * @throws CentralRepoException */ private static CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { @@ -227,8 +242,9 @@ public class CentralRepoDbManager { /** * This method updates the central repository schema if necessary. * - * @param db The database connectivity object. - * @param lock The acquired lock. + * @param db The database connectivity object. + * @param lock The acquired lock. + * * @throws CentralRepoException */ private static void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { @@ -257,9 +273,9 @@ public class CentralRepoDbManager { } /** - * This method upgrades the current Central Reposity schema to the newest version. If the - * upgrade fails, the Central Repository will be disabled and the current - * settings will be cleared. + * This method upgrades the current Central Reposity schema to the newest + * version. If the upgrade fails, the Central Repository will be disabled + * and the current settings will be cleared. */ @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) public static void upgradeDatabase() throws CentralRepoException { @@ -296,8 +312,6 @@ public class CentralRepoDbManager { } } - - private DatabaseTestResult testingStatus; private CentralRepoDbChoice selectedDbChoice; @@ -314,10 +328,10 @@ public class CentralRepoDbManager { dbSettingsSqlite = new SqliteCentralRepoSettings(); } - /** * This method retrieves the current multi-user database settings. - * @return The current multi-user database settings. + * + * @return The current multi-user database settings. */ public PostgresCentralRepoSettings getDbSettingsMultiUser() { return dbSettingsMultiUser; @@ -325,15 +339,18 @@ public class CentralRepoDbManager { /** * This method retrieves the current custom postgres database settings. - * @return The current custom postgres database settings. + * + * @return The current custom postgres database settings. */ public PostgresCentralRepoSettings getDbSettingsPostgres() { return dbSettingsPostgres; } /** - * This method returns the current SQLite database settings for central repository. - * @return The current SQLite database settings + * This method returns the current SQLite database settings for central + * repository. + * + * @return The current SQLite database settings */ public SqliteCentralRepoSettings getDbSettingsSqlite() { return dbSettingsSqlite; @@ -341,7 +358,8 @@ public class CentralRepoDbManager { /** * This method sets up the sqlite database with default settings. - * @throws CentralRepoException if unable to successfully set up database. + * + * @throws CentralRepoException if unable to successfully set up database. */ public void setupDefaultSqliteDb() throws CentralRepoException { // change in-memory settings to default sqlite @@ -354,67 +372,78 @@ public class CentralRepoDbManager { createDb(); curStatus = testStatus(); } - + // the only successful setup status is tested ok if (curStatus != DatabaseTestResult.TESTED_OK) { throw new CentralRepoException("Unable to successfully create sqlite database"); } - + // if successfully got here, then save the settings CentralRepoDbUtil.setUseCentralRepo(true); saveNewCentralRepo(); } /** - * This method returns if changes to the central repository configuration were - * successfully applied. + * This method returns if changes to the central repository configuration + * were successfully applied. * - * @return Returns true if the database configuration was successfully changed false - * if it was not. + * @return Returns true if the database configuration was successfully + * changed false if it was not. */ public boolean wasConfigurationChanged() { return configurationChanged; } private CentralRepoDbConnectivityManager getSelectedSettings() throws CentralRepoException { - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { return dbSettingsMultiUser; - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + } + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { return dbSettingsPostgres; - if (selectedDbChoice == CentralRepoDbChoice.SQLITE) + } + if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { return dbSettingsSqlite; - if (selectedDbChoice == CentralRepoDbChoice.DISABLED) + } + if (selectedDbChoice == CentralRepoDbChoice.DISABLED) { return null; - - throw new CentralRepoException("Unknown database type: " + selectedDbChoice); + } + + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsMultiUser); - if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) + } + if (selectedDbChoice == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { return new RdbmsCentralRepoFactory(CentralRepoPlatforms.POSTGRESQL, dbSettingsPostgres); - if (selectedDbChoice == CentralRepoDbChoice.SQLITE) + } + if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { return new RdbmsCentralRepoFactory(CentralRepoPlatforms.SQLITE, dbSettingsSqlite); - if (selectedDbChoice == CentralRepoDbChoice.DISABLED) + } + if (selectedDbChoice == CentralRepoDbChoice.DISABLED) { return null; - + } + throw new CentralRepoException("Unknown database type: " + selectedDbChoice); } /** * This method creates a central repo database if it does not already exist. - * @return True if successful; false if unsuccessful. + * + * @return True if successful; false if unsuccessful. + * * @throws CentralRepoException */ public boolean createDb() throws CentralRepoException { CentralRepoDbConnectivityManager selectedDbSettings = getSelectedSettings(); - if (selectedDbSettings == null) + if (selectedDbSettings == null) { throw new CentralRepoException("Unable to derive connectivity manager from settings: " + selectedDbChoice); + } boolean result = false; boolean dbCreated = true; - + if (!selectedDbSettings.verifyDatabaseExists()) { dbCreated = selectedDbSettings.createDatabase(); } @@ -493,18 +522,20 @@ public class CentralRepoDbManager { } /** - * This method retrieves the current status. - * Note: this could be a dirty value if testing of the connection has not been performed. - * @return The current status of the database connection. + * This method retrieves the current status. Note: this could be a dirty + * value if testing of the connection has not been performed. + * + * @return The current status of the database connection. */ public DatabaseTestResult getStatus() { return testingStatus; } /** - * This method retrieves the currently selected database choice. - * NOTE: This choice may not align with the saved setting. - * @return The currently selected database choice. + * This method retrieves the currently selected database choice. NOTE: This + * choice may not align with the saved setting. + * + * @return The currently selected database choice. */ public CentralRepoDbChoice getSelectedDbChoice() { return selectedDbChoice; @@ -518,8 +549,10 @@ public class CentralRepoDbManager { } /** - * This method sets the currently selected database choice and sets the testing status to untested. - * @param newSelected The new database choice. + * This method sets the currently selected database choice and sets the + * testing status to untested. + * + * @param newSelected The new database choice. */ public void setSelctedDbChoice(CentralRepoDbChoice newSelected) { selectedDbChoice = newSelected; @@ -527,8 +560,8 @@ public class CentralRepoDbManager { } /** - * This method tests whether or not the settings have been filled in for the UI. - * NOTE: This does not check the connectivity status of these settings. + * This method tests whether or not the settings have been filled in for the + * UI. NOTE: This does not check the connectivity status of these settings. * * @return True if database settings are valid. */ @@ -541,13 +574,11 @@ public class CentralRepoDbManager { dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); dbSettingsPostgres.setUserName(tbDbUsername); dbSettingsPostgres.setPassword(jpDbPassword); - } - else if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { + } else if (selectedDbChoice == CentralRepoDbChoice.SQLITE) { File databasePath = new File(tfDatabasePath); dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); dbSettingsSqlite.setDbDirectory(databasePath.getPath()); - } - else if (selectedDbChoice != CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { + } else if (selectedDbChoice != CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedDbChoice); } @@ -555,19 +586,21 @@ public class CentralRepoDbManager { } /** - * This method tests the current database settings to see if a valid connection can be made. - * @return The result of testing the connection. + * This method tests the current database settings to see if a valid + * connection can be made. + * + * @return The result of testing the connection. */ public DatabaseTestResult testStatus() { try { CentralRepoDbConnectivityManager manager = getSelectedSettings(); - if (manager != null) + if (manager != null) { testingStatus = manager.testStatus(); - } - catch (CentralRepoException e) { + } + } catch (CentralRepoException e) { logger.log(Level.WARNING, "unable to test status of db connection in central repo", e); } - + return testingStatus; } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java index 8f648a9945..d8bd1c43c3 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/CaseEventListener.java @@ -21,7 +21,9 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.EnumSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; @@ -64,6 +66,15 @@ final class CaseEventListener implements PropertyChangeListener { private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName()); private final ExecutorService jobProcessingExecutor; private static final String CASE_EVENT_THREAD_NAME = "Case-Event-Listener-%d"; + + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( + Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, + Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, + Case.Events.DATA_SOURCE_ADDED, + Case.Events.TAG_DEFINITION_CHANGED, + Case.Events.CURRENT_CASE, + Case.Events.DATA_SOURCE_NAME_CHANGED); CaseEventListener() { jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build()); @@ -82,6 +93,9 @@ final class CaseEventListener implements PropertyChangeListener { LOGGER.log(Level.SEVERE, "Failed to get instance of db manager.", ex); return; } + + // If any changes are made to which event types are handled the change + // must also be made to CASE_EVENTS_OF_INTEREST. switch (Case.Events.valueOf(evt.getPropertyName())) { case CONTENT_TAG_ADDED: case CONTENT_TAG_DELETED: { @@ -113,6 +127,20 @@ final class CaseEventListener implements PropertyChangeListener { break; } } + + /* + * Add all of our Case Event Listeners to the case. + */ + void installListeners() { + Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this); + } + + /* + * Remove all of our Case Event Listeners from the case. + */ + void uninstallListeners() { + Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this); + } private final class ContentTagTask implements Runnable { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index da58e8936b..d4f0253cd2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -101,7 +101,7 @@ public class Installer extends ModuleInstall { * central repository. */ private void addApplicationEventListeners() { - Case.addPropertyChangeListener(caseEventListener); + caseEventListener.installListeners(); ingestEventListener.installListeners(); } @@ -226,7 +226,7 @@ public class Installer extends ModuleInstall { * * THIS CODE IS NEVER EXECUTED. */ - Case.removePropertyChangeListener(caseEventListener); + caseEventListener.uninstallListeners(); caseEventListener.shutdown(); ingestEventListener.shutdown(); ingestEventListener.uninstallListeners(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form index 812a3984e8..d8460c48c7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form @@ -31,8 +31,14 @@ - - + + + + + + + + @@ -44,7 +50,13 @@ - + + + + + + + @@ -56,59 +68,15 @@ - - - - - - - + - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -119,227 +87,145 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - + + - + - - - - - - - - - - + + + + + + + + - + + + + + + - + + + + + + + + + - + + + + + + - + + + + + + + + + - + + + + + + - + + + + + + + + + - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -347,25 +233,38 @@ - + - + + + + + + + + + - + + + + + + @@ -376,6 +275,11 @@ + + + + + @@ -386,6 +290,11 @@ + + + + + @@ -402,7 +311,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index b9aadfdeee..675e7c8807 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -41,7 +41,6 @@ import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; -import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; @@ -61,15 +60,17 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettin public class EamDbSettingsDialog extends JDialog { private static final Logger logger = Logger.getLogger(EamDbSettingsDialog.class.getName()); - + private static final long serialVersionUID = 1L; - + /** - * This class handles displaying and rendering drop down menu for database choices in central repo. + * This class handles displaying and rendering drop down menu for database + * choices in central repo. */ private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { + private static final long serialVersionUID = 1L; - + @Override public Component getListCellRendererComponent( JList list, CentralRepoDbChoice value, @@ -82,22 +83,20 @@ public class EamDbSettingsDialog extends JDialog { return this; } } - - + private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; private final CentralRepoDbManager manager = new CentralRepoDbManager(); private final DbChoiceRenderer DB_CHOICE_RENDERER = new DbChoiceRenderer(); - + public EamDbSettingsDialog() { this(null); } - + private boolean isDbChoiceSelectable(CentralRepoDbChoice item) { - return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || manager.isPostgresMultiuserAllowed()); + return (item != CentralRepoDbChoice.POSTGRESQL_MULTIUSER || CentralRepoDbManager.isPostgresMultiuserAllowed()); } - - + /** * Creates new form EamDbSettingsDialog */ @@ -123,7 +122,7 @@ public class EamDbSettingsDialog extends JDialog { if (pathname.isDirectory()) { return true; } - return pathname.getName().equalsIgnoreCase(SqliteCentralRepoSettings.DEFAULT_DBNAME); + return pathname.getName().equalsIgnoreCase(SqliteCentralRepoSettings.DEFAULT_DBNAME); } @Override @@ -131,32 +130,34 @@ public class EamDbSettingsDialog extends JDialog { return "Directories and Central Repository databases"; } }); - + setupDbChoice(initialMenuItem); valid(); display(); } - private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item - CentralRepoDbChoice toSelect = (initialMenuItem == null) ? - (Arrays.asList(CentralRepoDbChoice.DB_CHOICES).contains(manager.getSelectedDbChoice())) ? - manager.getSelectedDbChoice() : - CentralRepoDbChoice.DB_CHOICES[0] : - initialMenuItem; - + CentralRepoDbChoice toSelect = (initialMenuItem == null) + ? (Arrays.asList(CentralRepoDbChoice.DB_CHOICES).contains(manager.getSelectedDbChoice())) + ? manager.getSelectedDbChoice() + : CentralRepoDbChoice.DB_CHOICES[0] + : initialMenuItem; + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); changeDbSelection(toSelect); } - - - - /** - * This method prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.). - * @param manager The manager to use when setting up the database. - * @param dialog If non-null value, validates settings and updates 'okay' button enabled state. - * @return Whether or not the ultimate status after prompts is okay to continue. + + /** + * This method prompts user based on testing status (i.e. failure to + * connect, invalid schema, db does not exist, etc.). + * + * @param manager The manager to use when setting up the database. + * @param dialog If non-null value, validates settings and updates 'okay' + * button enabled state. + * + * @return Whether or not the ultimate status after prompts is okay to + * continue. */ @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Central Repository Database", "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Central Repository Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", @@ -184,13 +185,13 @@ public class EamDbSettingsDialog extends JDialog { } return (manager.getStatus() == DatabaseTestResult.TESTED_OK); - } - - - /** - * This method prompts the user whether or not they would like to create a database in the instance that - * it doesn't exist. - * @param manager The manager to use when setting up the database. + } + + /** + * This method prompts the user whether or not they would like to create a + * database in the instance that it doesn't exist. + * + * @param manager The manager to use when setting up the database. * @param dialog If non-null value, validates settings and updates 'okay' * button enabled state. * @@ -204,26 +205,28 @@ public class EamDbSettingsDialog extends JDialog { JOptionPane.YES_NO_OPTION)) { try { manager.createDb(); - + } catch (CentralRepoException e) { onPromptStatusError(manager); return false; } - + if (dialog != null) { dialog.valid(); } return true; } - + return manager.testStatus() == DatabaseTestResult.TESTED_OK; } - /** - * When an error occurs while going through promptTestStatusWarning, this method is called. - * @param manager1 The manager to use as service class. - * @throws HeadlessException + * When an error occurs while going through promptTestStatusWarning, this + * method is called. + * + * @param manager1 The manager to use as service class. + * + * @throws HeadlessException */ private static void onPromptStatusError(CentralRepoDbManager manager1) { // in the event that there is a failure to connect, notify user with corresponding message @@ -240,7 +243,6 @@ public class EamDbSettingsDialog extends JDialog { Bundle.EamDbSettingsDialog_okButton_createDbError_title(), JOptionPane.WARNING_MESSAGE); } - /** * This method is called from within the constructor to initialize the form. @@ -250,15 +252,12 @@ public class EamDbSettingsDialog extends JDialog { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; fcDatabasePath = new javax.swing.JFileChooser(); pnButtons = new javax.swing.JPanel(); - bnCancel = new javax.swing.JButton(); - bnOk = new javax.swing.JButton(); pnSQLiteSettings = new javax.swing.JPanel(); lbDatabasePath = new javax.swing.JLabel(); - tfDatabasePath = new javax.swing.JTextField(); - bnDatabasePathFileOpen = new javax.swing.JButton(); lbHostName = new javax.swing.JLabel(); tbDbHostname = new javax.swing.JTextField(); lbPort = new javax.swing.JLabel(); @@ -267,17 +266,268 @@ public class EamDbSettingsDialog extends JDialog { tbDbUsername = new javax.swing.JTextField(); lbUserPassword = new javax.swing.JLabel(); jpDbPassword = new javax.swing.JPasswordField(); - cbDatabaseType = new javax.swing.JComboBox<>(); - lbSingleUserSqLite = new javax.swing.JLabel(); lbDatabaseType = new javax.swing.JLabel(); lbDatabaseDesc = new javax.swing.JLabel(); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767)); dataBaseFileScrollPane = new javax.swing.JScrollPane(); dataBaseFileTextArea = new javax.swing.JTextArea(); + pathPanel = new javax.swing.JPanel(); + tfDatabasePath = new javax.swing.JTextField(); + bnDatabasePathFileOpen = new javax.swing.JButton(); + typePanel = new javax.swing.JPanel(); + lbSingleUserSqLite = new javax.swing.JLabel(); + cbDatabaseType = new javax.swing.JComboBox<>(); + bnCancel = new javax.swing.JButton(); + bnOk = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setResizable(false); + javax.swing.GroupLayout pnButtonsLayout = new javax.swing.GroupLayout(pnButtons); + pnButtons.setLayout(pnButtonsLayout); + pnButtonsLayout.setHorizontalGroup( + pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 0, Short.MAX_VALUE) + ); + pnButtonsLayout.setVerticalGroup( + pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 25, Short.MAX_VALUE) + ); + + pnSQLiteSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + pnSQLiteSettings.setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabasePath.text")); // NOI18N + lbDatabasePath.setMaximumSize(new java.awt.Dimension(191, 16)); + lbDatabasePath.setPreferredSize(new java.awt.Dimension(100, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbDatabasePath, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbHostName.text")); // NOI18N + lbHostName.setMaximumSize(new java.awt.Dimension(195, 16)); + lbHostName.setPreferredSize(new java.awt.Dimension(110, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbHostName, gridBagConstraints); + + tbDbHostname.setPreferredSize(new java.awt.Dimension(519, 20)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 0, 6); + pnSQLiteSettings.add(tbDbHostname, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbPort.text")); // NOI18N + lbPort.setMaximumSize(new java.awt.Dimension(132, 16)); + lbPort.setPreferredSize(new java.awt.Dimension(90, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbPort, gridBagConstraints); + + tbDbPort.setPreferredSize(new java.awt.Dimension(519, 20)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 0, 6); + pnSQLiteSettings.add(tbDbPort, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserName.text")); // NOI18N + lbUserName.setMaximumSize(new java.awt.Dimension(172, 16)); + lbUserName.setPreferredSize(new java.awt.Dimension(100, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbUserName, gridBagConstraints); + + tbDbUsername.setPreferredSize(new java.awt.Dimension(519, 20)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 0, 6); + pnSQLiteSettings.add(tbDbUsername, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserPassword.text")); // NOI18N + lbUserPassword.setMaximumSize(new java.awt.Dimension(194, 16)); + lbUserPassword.setPreferredSize(new java.awt.Dimension(110, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 9; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbUserPassword, gridBagConstraints); + + jpDbPassword.setPreferredSize(new java.awt.Dimension(519, 20)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 9; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 0, 6); + pnSQLiteSettings.add(jpDbPassword, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseType, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseType.text")); // NOI18N + lbDatabaseType.setMaximumSize(new java.awt.Dimension(180, 14)); + lbDatabaseType.setMinimumSize(new java.awt.Dimension(80, 14)); + lbDatabaseType.setPreferredSize(new java.awt.Dimension(100, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(12, 14, 0, 0); + pnSQLiteSettings.add(lbDatabaseType, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseDesc, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseDesc.text")); // NOI18N + lbDatabaseDesc.setMaximumSize(new java.awt.Dimension(182, 16)); + lbDatabaseDesc.setPreferredSize(new java.awt.Dimension(100, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 14, 0, 0); + pnSQLiteSettings.add(lbDatabaseDesc, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 12; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + pnSQLiteSettings.add(filler1, gridBagConstraints); + + dataBaseFileScrollPane.setBorder(null); + + dataBaseFileTextArea.setEditable(false); + dataBaseFileTextArea.setBackground(new java.awt.Color(240, 240, 240)); + dataBaseFileTextArea.setColumns(20); + dataBaseFileTextArea.setLineWrap(true); + dataBaseFileTextArea.setRows(3); + dataBaseFileScrollPane.setViewportView(dataBaseFileTextArea); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridheight = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 15, 6); + pnSQLiteSettings.add(dataBaseFileScrollPane, gridBagConstraints); + + tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.text")); // NOI18N + tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N + tfDatabasePath.setPreferredSize(new java.awt.Dimension(420, 23)); + + org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N + bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnDatabasePathFileOpenActionPerformed(evt); + } + }); + + javax.swing.GroupLayout pathPanelLayout = new javax.swing.GroupLayout(pathPanel); + pathPanel.setLayout(pathPanelLayout); + pathPanelLayout.setHorizontalGroup( + pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pathPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(tfDatabasePath, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnDatabasePathFileOpen) + .addGap(0, 0, 0)) + ); + pathPanelLayout.setVerticalGroup( + pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pathPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(pathPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnDatabasePathFileOpen)) + .addGap(0, 0, 0)) + ); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 10, 0, 6); + pnSQLiteSettings.add(pathPanel, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(lbSingleUserSqLite, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbSingleUserSqLite.text")); // NOI18N + lbSingleUserSqLite.setPreferredSize(new java.awt.Dimension(381, 14)); + + cbDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice.DB_CHOICES)); + cbDatabaseType.setPreferredSize(new java.awt.Dimension(120, 20)); + cbDatabaseType.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbDatabaseTypeActionPerformed(evt); + } + }); + + javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel); + typePanel.setLayout(typePanelLayout); + typePanelLayout.setHorizontalGroup( + typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(typePanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(cbDatabaseType, 0, 210, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + typePanelLayout.setVerticalGroup( + typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(typePanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) + ); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(12, 10, 2, 0); + pnSQLiteSettings.add(typePanel, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnCancel.text")); // NOI18N bnCancel.setMaximumSize(new java.awt.Dimension(79, 23)); bnCancel.setMinimumSize(new java.awt.Dimension(79, 23)); @@ -295,170 +545,6 @@ public class EamDbSettingsDialog extends JDialog { } }); - javax.swing.GroupLayout pnButtonsLayout = new javax.swing.GroupLayout(pnButtons); - pnButtons.setLayout(pnButtonsLayout); - pnButtonsLayout.setHorizontalGroup( - pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnButtonsLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnOk) - .addGap(11, 11, 11) - .addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - - pnButtonsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancel, bnOk}); - - pnButtonsLayout.setVerticalGroup( - pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnButtonsLayout.createSequentialGroup() - .addGap(0, 0, 0) - .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnOk) - .addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0)) - ); - - pnSQLiteSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabasePath.text")); // NOI18N - lbDatabasePath.setPreferredSize(new java.awt.Dimension(80, 14)); - - tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.text")); // NOI18N - tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N - tfDatabasePath.setPreferredSize(new java.awt.Dimension(420, 23)); - - org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N - bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnDatabasePathFileOpenActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbHostName.text")); // NOI18N - lbHostName.setPreferredSize(new java.awt.Dimension(80, 14)); - - tbDbHostname.setPreferredSize(new java.awt.Dimension(509, 20)); - - org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbPort.text")); // NOI18N - lbPort.setPreferredSize(new java.awt.Dimension(80, 14)); - - tbDbPort.setPreferredSize(new java.awt.Dimension(509, 20)); - - org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserName.text")); // NOI18N - lbUserName.setPreferredSize(new java.awt.Dimension(80, 14)); - - tbDbUsername.setPreferredSize(new java.awt.Dimension(509, 20)); - - org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserPassword.text")); // NOI18N - lbUserPassword.setPreferredSize(new java.awt.Dimension(80, 14)); - - jpDbPassword.setPreferredSize(new java.awt.Dimension(509, 20)); - - cbDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbChoice.DB_CHOICES)); - cbDatabaseType.setPreferredSize(new java.awt.Dimension(120, 20)); - cbDatabaseType.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - cbDatabaseTypeActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(lbSingleUserSqLite, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbSingleUserSqLite.text")); // NOI18N - lbSingleUserSqLite.setPreferredSize(new java.awt.Dimension(381, 14)); - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseType, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseType.text")); // NOI18N - lbDatabaseType.setMaximumSize(new java.awt.Dimension(80, 14)); - lbDatabaseType.setMinimumSize(new java.awt.Dimension(80, 14)); - lbDatabaseType.setPreferredSize(new java.awt.Dimension(80, 14)); - - org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseDesc, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseDesc.text")); // NOI18N - lbDatabaseDesc.setPreferredSize(new java.awt.Dimension(80, 14)); - - dataBaseFileScrollPane.setBorder(null); - - dataBaseFileTextArea.setEditable(false); - dataBaseFileTextArea.setBackground(new java.awt.Color(240, 240, 240)); - dataBaseFileTextArea.setColumns(20); - dataBaseFileTextArea.setLineWrap(true); - dataBaseFileTextArea.setRows(3); - dataBaseFileScrollPane.setViewportView(dataBaseFileTextArea); - - javax.swing.GroupLayout pnSQLiteSettingsLayout = new javax.swing.GroupLayout(pnSQLiteSettings); - pnSQLiteSettings.setLayout(pnSQLiteSettingsLayout); - pnSQLiteSettingsLayout.setHorizontalGroup( - pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(lbDatabaseDesc, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 94, Short.MAX_VALUE) - .addComponent(lbUserPassword, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGap(10, 10, 10) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnDatabasePathFileOpen)) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)) - .addComponent(jpDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(tbDbUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(dataBaseFileScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 509, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addGap(55, 55, 55) - .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - ); - pnSQLiteSettingsLayout.setVerticalGroup( - pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbSingleUserSqLite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(lbDatabaseType, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnDatabasePathFileOpen)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(tbDbUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jpDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnSQLiteSettingsLayout.createSequentialGroup() - .addComponent(lbDatabaseDesc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(dataBaseFileScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) - ); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -466,17 +552,29 @@ public class EamDbSettingsDialog extends JDialog { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(pnButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(bnOk) + .addGap(11, 11, 11) + .addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE)) .addContainerGap()) ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancel, bnOk}); + layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnButtons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnButtons, 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, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnOk) + .addComponent(bnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); @@ -490,12 +588,10 @@ public class EamDbSettingsDialog extends JDialog { if (manager.getSelectedDbChoice() == CentralRepoDbChoice.SQLITE) { updatePostgresFields(false); updateSqliteFields(true); - } - else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { + } else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.POSTGRESQL_CUSTOM) { updatePostgresFields(true); updateSqliteFields(false); - } - else { + } else { updatePostgresFields(false); updateSqliteFields(false); } @@ -530,53 +626,63 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed - if (testStatusAndCreate(this, manager, this)) + if (testStatusAndCreate(this, manager, this)) { dispose(); + } }//GEN-LAST:event_bnOkActionPerformed - /** - * This method tests status for central repo db / creation and prompts user accordingly. - * @param parent The parent component (the anchor for displaying dialogs). - * @param manager The central repo db manager with settings to be tested and saved. - * @return Whether or not central repo db was successfully be created or found. + * This method tests status for central repo db / creation and prompts user + * accordingly. + * + * @param parent The parent component (the anchor for displaying dialogs). + * @param manager The central repo db manager with settings to be tested and + * saved. + * + * @return Whether or not central repo db was successfully be created or + * found. */ public static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager) { return testStatusAndCreate(parent, manager, null); } - - + /** - * This method tests status for central repo db / creation and prompts user accordingly. - * @param parent The parent component (the anchor for displaying dialogs). - * @param manager The central repo db manager with settings to be tested and saved. - * @param dialog The db settings dialog; if non-null, will validate okay button state. - * @return Whether or not central repo db was successfully be created or found. + * This method tests status for central repo db / creation and prompts user + * accordingly. + * + * @param parent The parent component (the anchor for displaying dialogs). + * @param manager The central repo db manager with settings to be tested and + * saved. + * @param dialog The db settings dialog; if non-null, will validate okay + * button state. + * + * @return Whether or not central repo db was successfully be created or + * found. */ private static boolean testStatusAndCreate(Component parent, CentralRepoDbManager manager, EamDbSettingsDialog dialog) { parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); manager.testStatus(); - - if (dialog != null) + + if (dialog != null) { dialog.valid(); - + } + boolean testedOk = promptTestStatusWarnings(manager, dialog); if (!testedOk) { parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return false; } - - try{ + + try { manager.saveNewCentralRepo(); - } - catch (CentralRepoException e) { + } catch (CentralRepoException e) { SwingUtilities.invokeLater(() -> { JOptionPane.showMessageDialog(parent, - Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), - Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), - JOptionPane.WARNING_MESSAGE); + Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), + Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), + JOptionPane.WARNING_MESSAGE); }); - + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return false; } @@ -584,14 +690,13 @@ public class EamDbSettingsDialog extends JDialog { parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return true; } - - + /** - * This method returns if changes to the central repository configuration were - * successfully applied. + * This method returns if changes to the central repository configuration + * were successfully applied. * - * @return True if the database configuration was successfully changed; false - * if it was not. + * @return True if the database configuration was successfully changed; + * false if it was not. */ public boolean wasConfigurationChanged() { return manager.wasConfigurationChanged(); @@ -611,11 +716,10 @@ public class EamDbSettingsDialog extends JDialog { if (isDbChoiceSelectable(selectedItem)) { manager.setSelctedDbChoice(selectedItem); cbDatabaseType.setSelectedItem(selectedItem); - } - else { + } else { cbDatabaseType.setSelectedItem(manager.getSelectedDbChoice()); } - + customizeComponents(); } @@ -627,14 +731,14 @@ public class EamDbSettingsDialog extends JDialog { private void displayDatabaseSettings(CentralRepoDbChoice choice) { boolean isSqlite = choice == CentralRepoDbChoice.SQLITE; boolean isPostgres = choice == CentralRepoDbChoice.POSTGRESQL_CUSTOM; - + lbDatabasePath.setVisible(isSqlite); tfDatabasePath.setVisible(isSqlite); lbDatabaseDesc.setVisible(isSqlite); dataBaseFileTextArea.setVisible(isSqlite); lbSingleUserSqLite.setVisible(isSqlite); bnDatabasePathFileOpen.setVisible(isSqlite); - + lbHostName.setVisible(isPostgres); tbDbHostname.setVisible(isPostgres); lbPort.setVisible(isPostgres); @@ -715,7 +819,7 @@ public class EamDbSettingsDialog extends JDialog { * Adds a change listener to a collection of text fields. * * @param textFields The text fields. - * @param listener The change listener. + * @param listener The change listener. */ private static void addDocumentListeners(Collection textFields, TextBoxChangedListener listener) { textFields.forEach((textField) -> { @@ -738,8 +842,7 @@ public class EamDbSettingsDialog extends JDialog { // && !tbDbName.getText().trim().isEmpty() && !tbDbUsername.getText().trim().isEmpty() && 0 < jpDbPassword.getPassword().length; - } - else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.SQLITE) { + } else if (manager.getSelectedDbChoice() == CentralRepoDbChoice.SQLITE) { result = !tfDatabasePath.getText().trim().isEmpty(); } @@ -756,7 +859,6 @@ public class EamDbSettingsDialog extends JDialog { && databaseSettingsAreValid(); } - /** * Validates that the form is filled out correctly for our usage. * @@ -782,9 +884,7 @@ public class EamDbSettingsDialog extends JDialog { return true; } - - - + /** * Tests whether or not the database settings are valid. * @@ -793,16 +893,15 @@ public class EamDbSettingsDialog extends JDialog { private boolean databaseSettingsAreValid() { try { manager.testDatabaseSettingsAreValid( - tbDbHostname.getText().trim(), - tbDbPort.getText().trim(), - tbDbUsername.getText().trim(), - tfDatabasePath.getText().trim(), + tbDbHostname.getText().trim(), + tbDbPort.getText().trim(), + tbDbUsername.getText().trim(), + tfDatabasePath.getText().trim(), new String(jpDbPassword.getPassword())); - } - catch (CentralRepoException | NumberFormatException | IllegalStateException e) { + } catch (CentralRepoException | NumberFormatException | IllegalStateException e) { return false; } - + return true; } @@ -854,11 +953,13 @@ public class EamDbSettingsDialog extends JDialog { private javax.swing.JLabel lbSingleUserSqLite; private javax.swing.JLabel lbUserName; private javax.swing.JLabel lbUserPassword; + private javax.swing.JPanel pathPanel; private javax.swing.JPanel pnButtons; private javax.swing.JPanel pnSQLiteSettings; private javax.swing.JTextField tbDbHostname; private javax.swing.JTextField tbDbPort; private javax.swing.JTextField tbDbUsername; private javax.swing.JTextField tfDatabasePath; + private javax.swing.JPanel typePanel; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form index 942a113ff8..158a83b7d2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.form @@ -65,16 +65,16 @@ - - - + + + - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index f668e2f6d0..7cb1e566dd 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -590,9 +590,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i .addComponent(organizationPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(casesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(cbUseCentralRepo, javax.swing.GroupLayout.PREFERRED_SIZE, 162, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(cbUseCentralRepo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ingestRunningWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 840, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 974, javax.swing.GroupLayout.PREFERRED_SIZE))) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.form index 9010e849e9..f7c005b254 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.form @@ -26,12 +26,12 @@ - + - + @@ -39,6 +39,7 @@ + @@ -50,122 +51,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -190,10 +86,21 @@ + + + + + + + + + + + @@ -219,66 +126,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -286,18 +306,40 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + @@ -312,7 +354,7 @@ - + @@ -320,7 +362,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.java index 47697f73ce..b4aa36f78a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageCasesDialog.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,6 +100,7 @@ final class ManageCasesDialog extends javax.swing.JDialog { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; casesSplitPane = new javax.swing.JSplitPane(); caseInfoPanel = new javax.swing.JPanel(); @@ -121,6 +122,7 @@ final class ManageCasesDialog extends javax.swing.JDialog { examinerEmailValueLabel = new javax.swing.JLabel(); examinerPhoneValueLabel = new javax.swing.JLabel(); closeButton = new javax.swing.JButton(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); casesPanel = new javax.swing.JPanel(); casesScrollPane = new javax.swing.JScrollPane(); casesTable = new javax.swing.JTable(); @@ -129,13 +131,29 @@ final class ManageCasesDialog extends javax.swing.JDialog { setMinimumSize(new java.awt.Dimension(400, 400)); casesSplitPane.setDividerLocation(380); + casesSplitPane.setResizeWeight(0.5); + + caseInfoPanel.setLayout(new java.awt.GridBagLayout()); dataSourcesTable.setAutoCreateRowSorter(true); dataSourcesTable.setModel(dataSourcesTableModel); dataSourcesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); dataSourcesScrollPane.setViewportView(dataSourcesTable); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 9; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(7, 22, 0, 12); + caseInfoPanel.add(dataSourcesScrollPane, gridBagConstraints); + notesScrollPane.setBorder(null); + notesScrollPane.setMinimumSize(new java.awt.Dimension(25, 54)); + notesScrollPane.setPreferredSize(new java.awt.Dimension(160, 70)); notesTextArea.setEditable(false); notesTextArea.setBackground(new java.awt.Color(240, 240, 240)); @@ -146,117 +164,177 @@ final class ManageCasesDialog extends javax.swing.JDialog { notesTextArea.setBorder(null); notesScrollPane.setViewportView(notesTextArea); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(7, 28, 0, 12); + caseInfoPanel.add(notesScrollPane, gridBagConstraints); + org.openide.awt.Mnemonics.setLocalizedText(caseInfoLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.caseInfoLabel.text")); // NOI18N + caseInfoLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + caseInfoLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(13, 12, 0, 0); + caseInfoPanel.add(caseInfoLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(dataSourcesLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.dataSourcesLabel.text")); // NOI18N + dataSourcesLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + dataSourcesLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 12, 0, 0); + caseInfoPanel.add(dataSourcesLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(notesLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.notesLabel.text")); // NOI18N + notesLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + notesLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(notesLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(orgLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.orgLabel.text")); // NOI18N + orgLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + orgLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(orgLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(caseNumberLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.caseNumberLabel.text")); // NOI18N + caseNumberLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + caseNumberLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(caseNumberLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(examinerEmailLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.examinerEmailLabel.text")); // NOI18N + examinerEmailLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + examinerEmailLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(examinerEmailLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(examinerNameLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.examinerNameLabel.text")); // NOI18N + examinerNameLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + examinerNameLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(examinerNameLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(examinerPhoneLabel, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.examinerPhoneLabel.text")); // NOI18N + examinerPhoneLabel.setMaximumSize(new java.awt.Dimension(237, 16)); + examinerPhoneLabel.setPreferredSize(new java.awt.Dimension(130, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(7, 18, 0, 0); + caseInfoPanel.add(examinerPhoneLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 7, 0, 12); + caseInfoPanel.add(orgValueLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 7, 0, 12); + caseInfoPanel.add(caseNumberValueLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 6, 0, 12); + caseInfoPanel.add(examinerNameValueLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(9, 6, 0, 12); + caseInfoPanel.add(examinerEmailValueLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 6, 0, 12); + caseInfoPanel.add(examinerPhoneValueLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ManageCasesDialog.class, "ManageCasesDialog.closeButton.text")); // NOI18N - closeButton.setMaximumSize(new java.awt.Dimension(65, 23)); + closeButton.setMaximumSize(new java.awt.Dimension(140, 23)); closeButton.setMinimumSize(new java.awt.Dimension(65, 23)); - closeButton.setPreferredSize(new java.awt.Dimension(65, 23)); + closeButton.setPreferredSize(new java.awt.Dimension(90, 23)); closeButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { closeButtonActionPerformed(evt); } }); - - javax.swing.GroupLayout caseInfoPanelLayout = new javax.swing.GroupLayout(caseInfoPanel); - caseInfoPanel.setLayout(caseInfoPanelLayout); - caseInfoPanelLayout.setHorizontalGroup( - caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(dataSourcesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(orgLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(caseNumberLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(examinerNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(examinerEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(examinerPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(caseNumberValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(orgValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGap(6, 6, 6) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(examinerNameValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(examinerEmailValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(examinerPhoneValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))) - .addComponent(notesLabel) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(notesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE)))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, caseInfoPanelLayout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(caseInfoLabel) - .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) - ); - caseInfoPanelLayout.setVerticalGroup( - caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, caseInfoPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(caseInfoLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(caseInfoPanelLayout.createSequentialGroup() - .addComponent(orgLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(caseNumberLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(caseNumberValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(examinerNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(examinerNameValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addComponent(orgValueLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(examinerEmailLabel)) - .addComponent(examinerEmailValueLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(caseInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(examinerPhoneLabel) - .addComponent(examinerPhoneValueLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(notesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(notesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dataSourcesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(dataSourcesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(7, 285, 13, 12); + caseInfoPanel.add(closeButton, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + caseInfoPanel.add(filler1, gridBagConstraints); casesSplitPane.setRightComponent(caseInfoPanel); @@ -270,13 +348,13 @@ final class ManageCasesDialog extends javax.swing.JDialog { casesPanelLayout.setHorizontalGroup( casesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(casesPanelLayout.createSequentialGroup() - .addComponent(casesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE) + .addComponent(casesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 318, Short.MAX_VALUE) .addGap(0, 0, 0)) ); casesPanelLayout.setVerticalGroup( casesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(casesPanelLayout.createSequentialGroup() - .addComponent(casesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE) + .addComponent(casesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 528, Short.MAX_VALUE) .addGap(40, 40, 40)) ); @@ -286,11 +364,11 @@ final class ManageCasesDialog extends javax.swing.JDialog { getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(casesSplitPane, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(casesSplitPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 850, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(casesSplitPane) + .addComponent(casesSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 570, Short.MAX_VALUE) ); pack(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java index dff44aa0c5..85373c06d2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/ManageOrganizationsDialog.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.optionspanel; import java.awt.Component; +import java.awt.Dialog; import java.util.List; import java.util.logging.Level; import javax.swing.DefaultListCellRenderer; @@ -51,12 +52,41 @@ public final class ManageOrganizationsDialog extends JDialog { @Messages({"ManageOrganizationsDialog.title.text=Manage Organizations"}) /** - * Creates new form ManageOrganizationsPanel + * Creates new form ManageOrganizationsPanel. + * @param parent The dialog parent. */ - public ManageOrganizationsDialog() { - super((JFrame) WindowManager.getDefault().getMainWindow(), + public ManageOrganizationsDialog(Dialog parent) { + super(parent, Bundle.ManageOrganizationsDialog_title_text(), true); // NON-NLS + init(); + } + + + /** + * Creates new form ManageOrganizationsPanel. + * @param parent The JFrame parent. + */ + public ManageOrganizationsDialog(JFrame parent) { + super(parent, + Bundle.ManageOrganizationsDialog_title_text(), + true); // NON-NLS + init(); + } + + + /** + * Creates new form ManageOrganizationsPanel. + */ + public ManageOrganizationsDialog() { + this((JFrame) WindowManager.getDefault().getMainWindow()); + } + + + /** + * To be run as a part of constructor initialization. + */ + private void init() { initComponents(); try { this.dbManager = CentralRepository.getInstance(); @@ -85,6 +115,7 @@ public final class ManageOrganizationsDialog extends JDialog { private void display() { this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); setVisible(true); + toFront(); } private void populateListAndSelect(CentralRepoOrganization selected) throws CentralRepoException { diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.form b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.form index 74ebe1bd30..ffd6af0ea7 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.form @@ -8,8 +8,11 @@ + + + - + @@ -29,7 +32,7 @@ - + @@ -37,10 +40,13 @@ - + + + + - + @@ -54,7 +60,7 @@ - + @@ -63,93 +69,94 @@ - - + + - - + + - - - + + + - - + + - + - - - - - - - - + + + + + - + + + + + + - - - - - - - - - + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + @@ -204,12 +211,15 @@ + + + - + @@ -251,6 +261,9 @@ + + + @@ -278,6 +291,15 @@ + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java index 5e7aa3adb4..b301e69d04 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java @@ -640,7 +640,8 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer countResultsRadioButton = new javax.swing.JRadioButton(); displayResultsLabel = new javax.swing.JLabel(); - setMinimumSize(new java.awt.Dimension(450, 570)); + setMaximumSize(new java.awt.Dimension(499, 646)); + setMinimumSize(new java.awt.Dimension(499, 646)); setResizable(false); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosed(java.awt.event.WindowEvent evt) { @@ -648,8 +649,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer } }); - jPanel1.setMaximumSize(null); - jPanel1.setPreferredSize(new java.awt.Dimension(450, 646)); + jPanel1.setMaximumSize(new java.awt.Dimension(499, 646)); + jPanel1.setMinimumSize(new java.awt.Dimension(499, 646)); + jPanel1.setPreferredSize(new java.awt.Dimension(499, 646)); jPanel1.setRequestFocusEnabled(false); org.openide.awt.Mnemonics.setLocalizedText(commonItemSearchDescription, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.commonItemSearchDescription.text")); // NOI18N @@ -677,12 +679,13 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer containerPanel.setBackground(new java.awt.Color(0, 0, 0)); containerPanel.setOpaque(false); + containerPanel.setPreferredSize(new java.awt.Dimension(477, 326)); javax.swing.GroupLayout containerPanelLayout = new javax.swing.GroupLayout(containerPanel); containerPanel.setLayout(containerPanelLayout); containerPanelLayout.setHorizontalGroup( containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 430, Short.MAX_VALUE) + .addGap(0, 0, Short.MAX_VALUE) ); containerPanelLayout.setVerticalGroup( containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -703,6 +706,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer percentageThresholdInputBox.setPreferredSize(new java.awt.Dimension(40, 24)); org.openide.awt.Mnemonics.setLocalizedText(percentageThresholdTextTwo, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.percentageThresholdTextTwo.text_1")); // NOI18N + percentageThresholdTextTwo.setMaximumSize(new java.awt.Dimension(260, 16)); org.openide.awt.Mnemonics.setLocalizedText(dataSourcesLabel, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.dataSourcesLabel.text")); // NOI18N @@ -713,6 +717,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonAttributePanel.class, "CommonAttributePanel.searchButton.text")); // NOI18N searchButton.setEnabled(false); searchButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + searchButton.setMaximumSize(new java.awt.Dimension(100, 25)); + searchButton.setMinimumSize(new java.awt.Dimension(100, 25)); + searchButton.setPreferredSize(new java.awt.Dimension(100, 25)); searchButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { searchButtonActionPerformed(evt); @@ -746,42 +753,44 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(intraCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addComponent(intraCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addComponent(scopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(37, 37, 37)) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(percentageThresholdCheck) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(percentageThresholdCheck, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE) + .addGap(1, 1, 1) .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE) .addContainerGap()) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, 330, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(searchButton) + .addComponent(errorText) + .addGap(6, 6, 6) + .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(containerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() - .addGap(20, 20, 20) - .addComponent(interCaseRadio, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE)))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(commonItemSearchDescription, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(interCaseRadio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(84, 84, 84)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()))) .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(30, 30, 30) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(displayResultsLabel)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(30, 30, 30) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(caseResultsRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 410, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(countResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addComponent(caseResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(49, 49, 49)) + .addComponent(countResultsRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(10, 10, 10)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(displayResultsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -800,7 +809,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(percentageThresholdCheck) .addComponent(percentageThresholdInputBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(percentageThresholdTextTwo)) + .addComponent(percentageThresholdTextTwo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(displayResultsLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -811,9 +820,9 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer .addComponent(dataSourcesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(searchButton) + .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(errorText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(14, 14, 14)) ); getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java index 25d7bf5519..8bf29e70ac 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java @@ -48,7 +48,8 @@ final class AccountDeviceInstanceNode extends AbstractNode { this.account = accountDeviceInstanceKey.getAccountDeviceInstance().getAccount(); setName(account.getTypeSpecificID()); setDisplayName(getName()); - setIconBaseWithExtension(Utils.getIconFilePath(account.getAccountType())); + String iconPath = Utils.getIconFilePath(account.getAccountType()); + this.setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) == '/' ? iconPath.substring(1) : iconPath); } AccountDeviceInstance getAccountDeviceInstance() { diff --git a/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java index 52136d1b1a..34e6339b68 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/PinAccountsAction.java @@ -32,7 +32,7 @@ import org.openide.util.NbBundle; final class PinAccountsAction extends AbstractCVTAction { static private final ImageIcon ICON = ImageUtilities.loadImageIcon( - "/org/sleuthkit/autopsy/communications/images/marker--plus.png", false); + "org/sleuthkit/autopsy/communications/images/marker--plus.png", false); private static final String SINGULAR_TEXT = Bundle.PinAccountsAction_singularText(); private static final String PLURAL_TEXT = Bundle.PinAccountsAction_pluralText(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java index 385ac3348b..ee71508162 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/ResetAndPinAccountsAction.java @@ -32,7 +32,7 @@ import org.openide.util.NbBundle; final class ResetAndPinAccountsAction extends AbstractCVTAction { private static final ImageIcon ICON = ImageUtilities.loadImageIcon( - "/org/sleuthkit/autopsy/communications/images/marker--pin.png", false); + "org/sleuthkit/autopsy/communications/images/marker--pin.png", false); private static final String SINGULAR_TEXT = Bundle.ResetAndPinAccountsAction_singularText(); private static final String PLURAL_TEXT = Bundle.ResetAndPinAccountsAction_pluralText(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java index 58ace503d9..0342d90310 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java +++ b/Core/src/org/sleuthkit/autopsy/communications/UnpinAccountsAction.java @@ -32,7 +32,7 @@ import org.openide.util.NbBundle; final class UnpinAccountsAction extends AbstractCVTAction { static final private ImageIcon ICON = ImageUtilities.loadImageIcon( - "/org/sleuthkit/autopsy/communications/images/marker--minus.png", false); + "org/sleuthkit/autopsy/communications/images/marker--minus.png", false); private static final String SINGULAR_TEXT = Bundle.UnpinAccountsAction_singularText(); private static final String PLURAL_TEXT = Bundle.UnpinAccountsAction_pluralText(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 263bb200e6..1799ebcb8d 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -43,7 +43,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Desktop; import java.awt.Dimension; -import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; @@ -110,7 +109,7 @@ import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.TskCoreException; -import org.sleuthkit.autopsy.uicomponents.WrapLayout; +import org.sleuthkit.autopsy.guiutils.WrapLayout; /** * A panel that goes in the Visualize tab of the Communications Visualization * Tool. Hosts an JGraphX mxGraphComponent that implements the communications @@ -245,7 +244,7 @@ final public class VisualizationPanel extends JPanel { setStateButtonsEnabled(); - toolbar.setLayout(new WrapLayout(FlowLayout.LEFT)); + toolbar.setLayout(new WrapLayout()); } @Subscribe diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/AccountSummary.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/AccountSummary.java index 5401f1a839..ff6607a84e 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/AccountSummary.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/AccountSummary.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.communications.relationships; -import com.google.gson.Gson; import java.util.Collection; import java.util.List; import java.util.Set; @@ -34,6 +33,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.FileAttachment; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; import org.sleuthkit.datamodel.CommunicationsUtils; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; /** * @@ -137,20 +137,23 @@ class AccountSummary { // count the attachments from the TSK_ATTACHMENTS attribute. BlackboardAttribute attachmentsAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS)); if (attachmentsAttr != null) { - String jsonVal = attachmentsAttr.getValueString(); - MessageAttachments msgAttachments = new Gson().fromJson(jsonVal, MessageAttachments.class); - - Collection fileAttachments = msgAttachments.getFileAttachments(); - for (FileAttachment fileAttachment : fileAttachments) { - attachmentCnt++; - long attachedFileObjId = fileAttachment.getObjectId(); - if (attachedFileObjId >= 0) { - AbstractFile attachedFile = artifact.getSleuthkitCase().getAbstractFileById(attachedFileObjId); - if (ImageUtils.thumbnailSupported(attachedFile)) { - mediaCnt++; - } + try { + MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class); + Collection fileAttachments = msgAttachments.getFileAttachments(); + for (FileAttachment fileAttachment : fileAttachments) { + attachmentCnt++; + long attachedFileObjId = fileAttachment.getObjectId(); + if (attachedFileObjId >= 0) { + AbstractFile attachedFile = artifact.getSleuthkitCase().getAbstractFileById(attachedFileObjId); + if (ImageUtils.thumbnailSupported(attachedFile)) { + mediaCnt++; + } + } } - } + } + catch (BlackboardJsonAttrUtil.InvalidJsonException ex) { + logger.log(Level.WARNING, String.format("Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex); + } } else { // backward compatibility - email message attachments are derived files, children of the message. attachmentCnt += artifact.getChildrenCount(); for (Content childContent : artifact.getChildren()) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/AttachmentThumbnailsChildren.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/AttachmentThumbnailsChildren.java index 74ee109b6f..1daffda703 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/AttachmentThumbnailsChildren.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/AttachmentThumbnailsChildren.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.communications.relationships; -import com.google.gson.Gson; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -38,6 +37,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.FileAttachment; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; @@ -89,17 +89,19 @@ final class AttachmentThumbnailsChildren extends Children.Keys { // Get the attachments from TSK_ATTACHMENTS attribute. BlackboardAttribute attachmentsAttr = bba.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS)); if (attachmentsAttr != null) { - - String jsonVal = attachmentsAttr.getValueString(); - MessageAttachments msgAttachments = new Gson().fromJson(jsonVal, MessageAttachments.class); - - Collection fileAttachments = msgAttachments.getFileAttachments(); - for (FileAttachment fileAttachment : fileAttachments) { - long attachedFileObjId = fileAttachment.getObjectId(); - if (attachedFileObjId >= 0) { - AbstractFile attachedFile = bba.getSleuthkitCase().getAbstractFileById(attachedFileObjId); - thumbnails.add(attachedFile); + try { + MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class); + Collection fileAttachments = msgAttachments.getFileAttachments(); + for (FileAttachment fileAttachment : fileAttachments) { + long attachedFileObjId = fileAttachment.getObjectId(); + if (attachedFileObjId >= 0) { + AbstractFile attachedFile = bba.getSleuthkitCase().getAbstractFileById(attachedFileObjId); + thumbnails.add(attachedFile); + } } + } + catch (BlackboardJsonAttrUtil.InvalidJsonException ex) { + LOGGER.log(Level.WARNING, String.format("Unable to parse json for MessageAttachments object in artifact: %s", bba.getName()), ex); } } else { // backward compatibility - email message attachments are derived files, children of the message. for (Content childContent : bba.getChildren()) { diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java index 038452dcd7..5070181e08 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/MessageNode.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.communications.relationships; -import com.google.gson.Gson; import java.util.logging.Level; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; @@ -40,6 +39,7 @@ import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; /** @@ -155,9 +155,14 @@ class MessageNode extends BlackboardArtifactNode { // Attachments are specified in an attribute TSK_ATTACHMENTS as JSON attribute BlackboardAttribute attachmentsAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ATTACHMENTS)); if (attachmentsAttr != null) { - String jsonVal = attachmentsAttr.getValueString(); - MessageAttachments msgAttachments = new Gson().fromJson(jsonVal, MessageAttachments.class); - attachmentsCount = msgAttachments.getAttachmentsCount(); + try { + MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class); + return msgAttachments.getAttachmentsCount(); + } + catch (BlackboardJsonAttrUtil.InvalidJsonException ex) { + logger.log(Level.WARNING, String.format("Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex); + return 0; + } } else { // legacy attachments may be children of message artifact. attachmentsCount = artifact.getChildrenCount(); } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index c0a6f73aaf..0c33d92daf 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -112,6 +112,8 @@ MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments MessageContentViewer.viewInNewWindowButton.text=View in New Window JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file: JPEGViewerDummy.jTextField1.text=jTextField1 +PDFViewer.encryptedDialog=This document is password protected. +PDFViewer.errorDialog=An error occurred while opening this PDF document. Check the logs for more information. You may continue to use this feature on other PDF documents. PListNode.KeyCol=Key PListNode.TypeCol=Type PListNode.ValueCol=Value diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/FileViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/FileViewer.java index 1b0d048f35..0a50fb0ec9 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/FileViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/FileViewer.java @@ -50,7 +50,8 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer new PListViewer(), new MediaFileViewer(), new HtmlViewer(), - new WindowsRegistryViewer() + new WindowsRegistryViewer(), + new PDFViewer() }; private FileTypeViewer lastViewer; diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index 8ea3867470..d314201f23 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.contentviewers; import org.sleuthkit.autopsy.datamodel.AttachmentNode; -import com.google.gson.Gson; import java.awt.Color; import java.awt.Component; import java.awt.ComponentOrientation; @@ -76,6 +75,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEX import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.FileAttachment; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.Attachment; @@ -637,16 +637,19 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont if (attachmentsAttr != null) { attachments = new HashSet<>(); - String jsonVal = attachmentsAttr.getValueString(); - MessageAttachments msgAttachments = new Gson().fromJson(jsonVal, MessageAttachments.class); - - Collection fileAttachments = msgAttachments.getFileAttachments(); - for (FileAttachment fileAttachment : fileAttachments) { - attachments.add(fileAttachment); - } - Collection urlAttachments = msgAttachments.getUrlAttachments(); - for (URLAttachment urlAttachment : urlAttachments) { - attachments.add(urlAttachment); + try { + MessageAttachments msgAttachments = BlackboardJsonAttrUtil.fromAttribute(attachmentsAttr, MessageAttachments.class); + Collection fileAttachments = msgAttachments.getFileAttachments(); + for (FileAttachment fileAttachment : fileAttachments) { + attachments.add(fileAttachment); + } + Collection urlAttachments = msgAttachments.getUrlAttachments(); + for (URLAttachment urlAttachment : urlAttachments) { + attachments.add(urlAttachment); + } + } + catch (BlackboardJsonAttrUtil.InvalidJsonException ex) { + LOGGER.log(Level.WARNING, String.format("Unable to parse json for MessageAttachments object in artifact: %s", artifact.getName()), ex); } } else { // For backward compatibility - email attachements are derived files and children of the email message artifact attachments = new HashSet<>(); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/PDFViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/PDFViewer.java new file mode 100755 index 0000000000..52c6a93558 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/PDFViewer.java @@ -0,0 +1,192 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.contentviewers; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +import org.openide.util.NbBundle; + +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.ReadContentInputStream; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; + +import org.icepdf.core.exceptions.PDFException; +import org.icepdf.core.exceptions.PDFSecurityException; +import org.icepdf.core.pobjects.Document; + +import org.icepdf.ri.common.ComponentKeyBinding; +import org.icepdf.ri.common.SwingController; +import org.icepdf.ri.common.SwingViewBuilder; +import org.icepdf.ri.common.views.DocumentViewControllerImpl; +import org.icepdf.ri.common.views.DocumentViewModelImpl; +import org.icepdf.ri.util.PropertiesManager; + +/** + * Application content viewer for PDF files. + */ +public class PDFViewer implements FileTypeViewer { + + private static final Logger logger = Logger.getLogger(PDFViewer.class.getName()); + + private JPanel container; + private final PropertiesManager propsManager; + + public PDFViewer() { + container = createNewContainer(); + propsManager = getCustomProperties(); + } + + @Override + public List getSupportedMIMETypes() { + return Arrays.asList("application/pdf"); + } + + @Override + public void setFile(AbstractFile file) { + // The 'C' in IcePDFs MVC set up. + SwingController controller = new SwingController(); + + // Builder for the 'V' in IcePDFs MVC set up + SwingViewBuilder viewBuilder = new SwingViewBuilder(controller, propsManager); + + // The 'V' in IcePDFs MVC set up. + JPanel icePdfPanel = viewBuilder.buildViewerPanel(); + + // This connects keyboard commands performed on the view to the controller. + // The only keyboard commands that the controller supports is Ctrl-C for + // copying selected text. + ComponentKeyBinding.install(controller, icePdfPanel); + + // Ensure the preferredSize is in sync with the parent container. + icePdfPanel.setPreferredSize(this.container.getPreferredSize()); + + // Add the IcePDF view to the center of our container. + this.container.add(icePdfPanel, BorderLayout.CENTER); + + // Document is the 'M' in IcePDFs MVC set up. Read the data needed to + // populate the model in the background. + new SwingWorker() { + @Override + protected Document doInBackground() throws PDFException, PDFSecurityException, IOException { + ReadContentInputStream stream = new ReadContentInputStream(file); + Document doc = new Document(); + // This will read the stream into memory. + doc.setInputStream(stream, null); + return doc; + } + + @Override + protected void done() { + // Customize the view selection modes on the EDT. Each of these + // will cause UI widgets to be updated. + try { + Document doc = get(); + controller.openDocument(doc, null); + // This makes the PDF viewer appear as one continuous + // document, which is the default for most popular PDF viewers. + controller.setPageViewMode(DocumentViewControllerImpl.ONE_COLUMN_VIEW, true); + // This makes it possible to select text by left clicking and dragging. + controller.setDisplayTool(DocumentViewModelImpl.DISPLAY_TOOL_TEXT_SELECTION); + } catch (InterruptedException ex) { + // Do nothing. + } catch (ExecutionException ex) { + Throwable exCause = ex.getCause(); + if (exCause instanceof PDFSecurityException) { + showEncryptionDialog(); + } else { + logger.log(Level.WARNING, String.format("PDF content viewer " + + "was unable to open document with id %d and name %s", + file.getId(), file.getName()), ex); + showErrorDialog(); + } + } + } + }.execute(); + } + + @Override + public Component getComponent() { + return container; + } + + @Override + public void resetComponent() { + container = createNewContainer(); + } + + // The container should have a BorderLayout otherwise the IcePDF panel may + // not be visible. + private JPanel createNewContainer() { + return new JPanel(new BorderLayout()); + } + + @Override + public boolean isSupported(AbstractFile file) { + return getSupportedMIMETypes().contains(file.getMIMEType()); + } + + /** + * Sets property values that will control how the view will be constructed + * in IcePDFs MVC set up. + */ + private PropertiesManager getCustomProperties() { + Properties props = new Properties(); + + // See link for available properties. https://www.icesoft.org/wiki/display/PDF/Customizing+the+Viewer + props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_SAVE, "false"); + props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_OPEN, "false"); + props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_PRINT, "false"); + props.setProperty(PropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION, "false"); + props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITYPANE_ANNOTATION, "false"); + + // This suppresses a pop-up, from IcePDF, that asks if you'd like to + // save configuration changes to disk. + props.setProperty("application.showLocalStorageDialogs", "false"); + + ResourceBundle defaultMessageBundle = ResourceBundle.getBundle(PropertiesManager.DEFAULT_MESSAGE_BUNDLE); + return new PropertiesManager(System.getProperties(), props, defaultMessageBundle); + } + + @NbBundle.Messages({ + "PDFViewer.errorDialog=An error occurred while opening this PDF document. " + + "Check the logs for more information. You may continue to use " + + "this feature on other PDF documents." + }) + private void showErrorDialog() { + MessageNotifyUtil.Message.error(Bundle.PDFViewer_errorDialog()); + } + + @NbBundle.Messages({ + "PDFViewer.encryptedDialog=This document is password protected." + }) + private void showEncryptionDialog() { + MessageNotifyUtil.Message.error(Bundle.PDFViewer_encryptedDialog()); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form index 333a5b8053..6253570c82 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.form @@ -27,10 +27,10 @@ - + - + @@ -43,124 +43,60 @@ + - - - - - - - - - - - - - - - - - + - - - - - - + + + + + + - + + + + - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - + + + + + + + + + + - + - - + + + + + + @@ -168,66 +104,122 @@ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + @@ -244,8 +236,14 @@ + + + + + + - + @@ -255,6 +253,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -262,33 +317,56 @@ + + + + + + + + + + + + + + + + + + + + - + - - - - - + + - - - - - + + + + + + + + + + + @@ -299,9 +377,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java index 931deba27e..95cbee43b7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/StringsContentPanel.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.contentviewers.textcontentviewer; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.Arrays; import java.util.List; import java.util.logging.Level; import org.openide.util.NbBundle; @@ -32,6 +33,7 @@ import org.sleuthkit.autopsy.coreutils.StringExtract; import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractResult; import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT; import org.sleuthkit.autopsy.datamodel.StringContent; +import org.sleuthkit.autopsy.guiutils.WrapLayout; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TskCoreException; @@ -78,6 +80,11 @@ public class StringsContentPanel extends javax.swing.JPanel { languageCombo.addItem(s); }); + // use wrap layout for better component wrapping + WrapLayout layout = new WrapLayout(0,5); + layout.setOppositeAligned(Arrays.asList(panelScriptSelect)); + controlPanel.setLayout(layout); + } final void resetDisplay() { @@ -105,21 +112,33 @@ public class StringsContentPanel extends javax.swing.JPanel { rightClickMenu = new javax.swing.JPopupMenu(); copyMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem(); + controlPanel = new javax.swing.JPanel(); + javax.swing.JPanel panelPageOfCount = new javax.swing.JPanel(); + pageLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed1 = new javax.swing.JSeparator(); + currentPageLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed2 = new javax.swing.JSeparator(); + ofLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed3 = new javax.swing.JSeparator(); + totalPageLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed4 = new javax.swing.JSeparator(); + javax.swing.JPanel panelPageNextPrevButton = new javax.swing.JPanel(); + pageLabel2 = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed5 = new javax.swing.JSeparator(); + prevPageButton = new javax.swing.JButton(); + nextPageButton = new javax.swing.JButton(); + javax.swing.JSeparator jSepMed6 = new javax.swing.JSeparator(); + javax.swing.JPanel panelGoToPage = new javax.swing.JPanel(); + goToPageLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepSm1 = new javax.swing.JSeparator(); + goToPageTextField = new javax.swing.JTextField(); + javax.swing.JSeparator jSepMed7 = new javax.swing.JSeparator(); + panelScriptSelect = new javax.swing.JPanel(); + languageLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepSm2 = new javax.swing.JSeparator(); + languageCombo = new javax.swing.JComboBox<>(); outputScrollPane = new javax.swing.JScrollPane(); outputViewPane = new javax.swing.JTextPane(); - controlScrollPane = new javax.swing.JScrollPane(); - controlPanel = new javax.swing.JPanel(); - totalPageLabel = new javax.swing.JLabel(); - ofLabel = new javax.swing.JLabel(); - currentPageLabel = new javax.swing.JLabel(); - pageLabel = new javax.swing.JLabel(); - nextPageButton = new javax.swing.JButton(); - pageLabel2 = new javax.swing.JLabel(); - prevPageButton = new javax.swing.JButton(); - goToPageLabel = new javax.swing.JLabel(); - goToPageTextField = new javax.swing.JTextField(); - languageCombo = new javax.swing.JComboBox<>(); - languageLabel = new javax.swing.JLabel(); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.copyMenuItem.text")); // NOI18N rightClickMenu.add(copyMenuItem); @@ -127,47 +146,62 @@ public class StringsContentPanel extends javax.swing.JPanel { selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.selectAllMenuItem.text")); // NOI18N rightClickMenu.add(selectAllMenuItem); - setMinimumSize(new java.awt.Dimension(5, 5)); - setPreferredSize(new java.awt.Dimension(100, 58)); + setMinimumSize(new java.awt.Dimension(250, 5)); + setPreferredSize(new java.awt.Dimension(250, 58)); + setLayout(new java.awt.BorderLayout()); - outputScrollPane.setPreferredSize(new java.awt.Dimension(640, 402)); + controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 0)); - outputViewPane.setEditable(false); - outputViewPane.setPreferredSize(new java.awt.Dimension(100, 40)); - outputScrollPane.setViewportView(outputViewPane); - - controlScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - controlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); - - totalPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.totalPageLabel.text_1")); // NOI18N - - ofLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.ofLabel.text_1")); // NOI18N - - currentPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.currentPageLabel.text_1")); // NOI18N - currentPageLabel.setMaximumSize(new java.awt.Dimension(18, 14)); - currentPageLabel.setPreferredSize(new java.awt.Dimension(18, 14)); + panelPageOfCount.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); pageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.pageLabel.text_1")); // NOI18N - pageLabel.setMaximumSize(new java.awt.Dimension(33, 14)); - pageLabel.setMinimumSize(new java.awt.Dimension(33, 14)); + pageLabel.setMaximumSize(new java.awt.Dimension(33, 25)); + pageLabel.setMinimumSize(new java.awt.Dimension(33, 25)); + pageLabel.setPreferredSize(new java.awt.Dimension(32, 25)); + panelPageOfCount.add(pageLabel); - nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N - nextPageButton.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.nextPageButton.text")); // NOI18N - nextPageButton.setBorderPainted(false); - nextPageButton.setContentAreaFilled(false); - nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N - nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - nextPageButton.setPreferredSize(new java.awt.Dimension(55, 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) { - nextPageButtonActionPerformed(evt); - } - }); + jSepMed1.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageOfCount.add(jSepMed1); + + currentPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.currentPageLabel.text_1")); // NOI18N + currentPageLabel.setMaximumSize(new java.awt.Dimension(18, 25)); + currentPageLabel.setMinimumSize(new java.awt.Dimension(7, 25)); + currentPageLabel.setPreferredSize(new java.awt.Dimension(18, 25)); + panelPageOfCount.add(currentPageLabel); + + jSepMed2.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageOfCount.add(jSepMed2); + + ofLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.ofLabel.text_1")); // NOI18N + ofLabel.setMaximumSize(new java.awt.Dimension(11, 25)); + ofLabel.setMinimumSize(new java.awt.Dimension(11, 25)); + ofLabel.setPreferredSize(new java.awt.Dimension(11, 25)); + panelPageOfCount.add(ofLabel); + + jSepMed3.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageOfCount.add(jSepMed3); + + totalPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.totalPageLabel.text_1")); // NOI18N + totalPageLabel.setMaximumSize(new java.awt.Dimension(21, 25)); + totalPageLabel.setMinimumSize(new java.awt.Dimension(21, 25)); + totalPageLabel.setPreferredSize(new java.awt.Dimension(21, 25)); + panelPageOfCount.add(totalPageLabel); + + jSepMed4.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageOfCount.add(jSepMed4); + + controlPanel.add(panelPageOfCount); + + panelPageNextPrevButton.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); pageLabel2.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.pageLabel2.text")); // NOI18N - pageLabel2.setMaximumSize(new java.awt.Dimension(29, 14)); - pageLabel2.setMinimumSize(new java.awt.Dimension(29, 14)); + pageLabel2.setMaximumSize(new java.awt.Dimension(29, 25)); + pageLabel2.setMinimumSize(new java.awt.Dimension(29, 25)); + pageLabel2.setPreferredSize(new java.awt.Dimension(29, 25)); + panelPageNextPrevButton.add(pageLabel2); + + jSepMed5.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageNextPrevButton.add(jSepMed5); prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N prevPageButton.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.prevPageButton.text")); // NOI18N @@ -175,98 +209,90 @@ public class StringsContentPanel extends javax.swing.JPanel { prevPageButton.setContentAreaFilled(false); prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - prevPageButton.setPreferredSize(new java.awt.Dimension(55, 23)); + prevPageButton.setMaximumSize(new java.awt.Dimension(25, 25)); + prevPageButton.setMinimumSize(new java.awt.Dimension(20, 25)); + prevPageButton.setPreferredSize(new java.awt.Dimension(25, 25)); prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N prevPageButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { prevPageButtonActionPerformed(evt); } }); + panelPageNextPrevButton.add(prevPageButton); + + nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N + nextPageButton.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.nextPageButton.text")); // NOI18N + nextPageButton.setBorderPainted(false); + nextPageButton.setContentAreaFilled(false); + nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N + nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + nextPageButton.setMaximumSize(new java.awt.Dimension(25, 25)); + nextPageButton.setMinimumSize(new java.awt.Dimension(20, 25)); + nextPageButton.setPreferredSize(new java.awt.Dimension(25, 25)); + 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) { + nextPageButtonActionPerformed(evt); + } + }); + panelPageNextPrevButton.add(nextPageButton); + + jSepMed6.setPreferredSize(new java.awt.Dimension(5, 0)); + panelPageNextPrevButton.add(jSepMed6); + + controlPanel.add(panelPageNextPrevButton); + + panelGoToPage.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); goToPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.goToPageLabel.text")); // NOI18N + panelGoToPage.add(goToPageLabel); + + jSepSm1.setPreferredSize(new java.awt.Dimension(2, 0)); + panelGoToPage.add(jSepSm1); goToPageTextField.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.goToPageTextField.text")); // NOI18N + goToPageTextField.setMaximumSize(new java.awt.Dimension(2147483647, 25)); + goToPageTextField.setMinimumSize(new java.awt.Dimension(50, 25)); + goToPageTextField.setPreferredSize(new java.awt.Dimension(70, 25)); goToPageTextField.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { goToPageTextFieldActionPerformed(evt); } }); + panelGoToPage.add(goToPageTextField); + + jSepMed7.setPreferredSize(new java.awt.Dimension(5, 0)); + panelGoToPage.add(jSepMed7); + + controlPanel.add(panelGoToPage); + + panelScriptSelect.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); + + languageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.text")); // NOI18N + languageLabel.setToolTipText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.toolTipText")); // NOI18N + panelScriptSelect.add(languageLabel); + + jSepSm2.setPreferredSize(new java.awt.Dimension(2, 0)); + panelScriptSelect.add(jSepSm2); languageCombo.setToolTipText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageCombo.toolTipText")); // NOI18N + languageCombo.setMinimumSize(new java.awt.Dimension(150, 25)); + languageCombo.setPreferredSize(new java.awt.Dimension(150, 25)); languageCombo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { languageComboActionPerformed(evt); } }); + panelScriptSelect.add(languageCombo); - languageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.text")); // NOI18N - languageLabel.setToolTipText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.toolTipText")); // NOI18N + controlPanel.add(panelScriptSelect); - javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); - controlPanel.setLayout(controlPanelLayout); - controlPanelLayout.setHorizontalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(ofLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(totalPageLabel) - .addGap(50, 50, 50) - .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(goToPageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(languageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(languageCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - controlPanelLayout.setVerticalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(ofLabel) - .addComponent(totalPageLabel)) - .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(goToPageLabel) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(languageCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(languageLabel))) - .addGap(0, 0, 0)) - ); + add(controlPanel, java.awt.BorderLayout.NORTH); - controlScrollPane.setViewportView(controlPanel); + outputViewPane.setEditable(false); + outputScrollPane.setViewportView(outputViewPane); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(outputScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(7, 7, 7) - .addComponent(outputScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE)) - ); + add(outputScrollPane, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents private void languageComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_languageComboActionPerformed @@ -318,7 +344,6 @@ public class StringsContentPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel controlPanel; - private javax.swing.JScrollPane controlScrollPane; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JLabel currentPageLabel; private javax.swing.JLabel goToPageLabel; @@ -331,6 +356,7 @@ public class StringsContentPanel extends javax.swing.JPanel { private javax.swing.JTextPane outputViewPane; private javax.swing.JLabel pageLabel; private javax.swing.JLabel pageLabel2; + private javax.swing.JPanel panelScriptSelect; private javax.swing.JButton prevPageButton; private javax.swing.JPopupMenu rightClickMenu; private javax.swing.JMenuItem selectAllMenuItem; diff --git a/Core/src/org/sleuthkit/autopsy/core/Installer.java b/Core/src/org/sleuthkit/autopsy/core/Installer.java index 65b5fbacdb..2d2357374a 100644 --- a/Core/src/org/sleuthkit/autopsy/core/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/core/Installer.java @@ -47,6 +47,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; +import org.sleuthkit.autopsy.python.JythonModuleLoader; /** * Wrapper over Installers in packages in Core module. This is the main @@ -389,7 +390,28 @@ public class Installer extends ModuleInstall { logger.log(Level.WARNING, msg, e); } } - logger.log(Level.INFO, "Autopsy Core restore completed"); //NON-NLS + logger.log(Level.INFO, "Autopsy Core restore completed"); //NON-NLS + preloadJython(); + } + + + /** + * Runs an initial load of the Jython modules to speed up subsequent loads. + */ + private void preloadJython() { + Runnable loader = () -> { + try { + JythonModuleLoader.getIngestModuleFactories(); + JythonModuleLoader.getGeneralReportModules(); + } + catch (Exception ex) { + // This is a firewall exception to ensure that any possible exception caused + // by this initial load of the Jython modules are caught and logged. + logger.log(Level.SEVERE, "There was an error while doing an initial load of python plugins.", ex); + } + + }; + new Thread(loader).start(); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.form index 15993c7cfe..394f5a3198 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.form @@ -56,47 +56,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.java index a62d3a1459..ac6dbc8216 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AdvancedConfigurationDialog.java @@ -70,12 +70,14 @@ public class AdvancedConfigurationDialog extends javax.swing.JDialog { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; jSeparator1 = new javax.swing.JSeparator(); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 4), new java.awt.Dimension(0, 4), new java.awt.Dimension(0, 4)); jPanel1 = new javax.swing.JPanel(); applyButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); + filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 4), new java.awt.Dimension(0, 4), new java.awt.Dimension(0, 4)); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -86,35 +88,40 @@ public class AdvancedConfigurationDialog extends javax.swing.JDialog { jPanel1.setMaximumSize(new java.awt.Dimension(4000, 27)); jPanel1.setMinimumSize(new java.awt.Dimension(100, 27)); jPanel1.setPreferredSize(new java.awt.Dimension(400, 27)); + jPanel1.setLayout(new java.awt.GridBagLayout()); applyButton.setText(org.openide.util.NbBundle.getMessage(AdvancedConfigurationDialog.class, "AdvancedConfigurationDialog.applyButton.text")); // NOI18N + applyButton.setMaximumSize(new java.awt.Dimension(150, 25)); + applyButton.setMinimumSize(new java.awt.Dimension(71, 25)); + applyButton.setPreferredSize(new java.awt.Dimension(71, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0); + jPanel1.add(applyButton, gridBagConstraints); cancelButton.setText(org.openide.util.NbBundle.getMessage(AdvancedConfigurationDialog.class, "AdvancedConfigurationDialog.cancelButton.text")); // NOI18N + cancelButton.setMaximumSize(new java.awt.Dimension(150, 25)); cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancelButtonActionPerformed(evt); } }); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap(242, Short.MAX_VALUE) - .addComponent(applyButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(12, 12, 12)) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(applyButton) - .addComponent(cancelButton)) - .addGap(0, 4, Short.MAX_VALUE)) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 7, 2, 12); + jPanel1.add(cancelButton, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + jPanel1.add(filler3, gridBagConstraints); getContentPane().add(jPanel1); getContentPane().add(filler2); @@ -131,6 +138,7 @@ public class AdvancedConfigurationDialog extends javax.swing.JDialog { private javax.swing.JButton cancelButton; private javax.swing.Box.Filler filler1; private javax.swing.Box.Filler filler2; + private javax.swing.Box.Filler filler3; private javax.swing.JPanel jPanel1; private javax.swing.JSeparator jSeparator1; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form index fc2e7d551d..5827ce617f 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form @@ -75,67 +75,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -143,6 +101,11 @@ + + + + + @@ -150,15 +113,20 @@ - + - + + + + + + @@ -166,6 +134,11 @@ + + + + + @@ -193,6 +166,11 @@ + + + + + @@ -206,6 +184,11 @@ + + + + + @@ -233,8 +216,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index fb80ad86f2..78ccd6e4ec 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -202,6 +202,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; rightClickMenu = new javax.swing.JPopupMenu(); copyMenuItem = new javax.swing.JMenuItem(); @@ -216,6 +217,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat pageLabel2 = new javax.swing.JLabel(); prevPageButton = new javax.swing.JButton(); artifactLabel = new javax.swing.JLabel(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); resultsTableScrollPane = new javax.swing.JScrollPane(); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.copyMenuItem.text")); // NOI18N @@ -230,17 +232,48 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); jPanel1.setPreferredSize(new java.awt.Dimension(620, 58)); + jPanel1.setLayout(new java.awt.GridBagLayout()); totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.totalPageLabel.text")); // NOI18N + totalPageLabel.setMaximumSize(new java.awt.Dimension(40, 16)); + totalPageLabel.setPreferredSize(new java.awt.Dimension(25, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); + jPanel1.add(totalPageLabel, gridBagConstraints); ofLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.ofLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); + jPanel1.add(ofLabel, gridBagConstraints); currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.currentPageLabel.text")); // NOI18N - currentPageLabel.setMaximumSize(new java.awt.Dimension(18, 14)); + currentPageLabel.setMaximumSize(new java.awt.Dimension(38, 14)); currentPageLabel.setMinimumSize(new java.awt.Dimension(18, 14)); - currentPageLabel.setPreferredSize(new java.awt.Dimension(18, 14)); + currentPageLabel.setPreferredSize(new java.awt.Dimension(20, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(4, 7, 0, 0); + jPanel1.add(currentPageLabel, gridBagConstraints); pageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.pageLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(3, 12, 0, 0); + jPanel1.add(pageLabel, gridBagConstraints); nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.nextPageButton.text")); // NOI18N @@ -255,10 +288,23 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat nextPageButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 35, 0); + jPanel1.add(nextPageButton, gridBagConstraints); pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.pageLabel2.text")); // NOI18N pageLabel2.setMaximumSize(new java.awt.Dimension(29, 14)); pageLabel2.setMinimumSize(new java.awt.Dimension(29, 14)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(3, 41, 0, 0); + jPanel1.add(pageLabel2, gridBagConstraints); prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.prevPageButton.text")); // NOI18N @@ -273,51 +319,25 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat prevPageButtonActionPerformed(evt); } }); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(pageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(ofLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(totalPageLabel) - .addGap(41, 41, 41) - .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(383, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap(280, Short.MAX_VALUE) - .addComponent(artifactLabel) - .addContainerGap(84, Short.MAX_VALUE))) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(pageLabel) - .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(ofLabel) - .addComponent(totalPageLabel)) - .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(35, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(artifactLabel) - .addGap(0, 58, Short.MAX_VALUE))) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 35, 0); + jPanel1.add(prevPageButton, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; + gridBagConstraints.insets = new java.awt.Insets(3, 0, 0, 8); + jPanel1.add(artifactLabel, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 0.1; + jPanel1.add(filler1, gridBagConstraints); jScrollPane1.setViewportView(jPanel1); @@ -359,6 +379,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat private javax.swing.JLabel artifactLabel; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JLabel currentPageLabel; + private javax.swing.Box.Filler filler1; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton nextPageButton; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java index 807acc5e07..c0aa235223 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java @@ -56,7 +56,7 @@ import static org.sleuthkit.autopsy.corecomponents.Bundle.*; import org.sleuthkit.autopsy.corecomponents.ResultViewerPersistence.SortCriterion; import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.uicomponents.WrapLayout; +import org.sleuthkit.autopsy.guiutils.WrapLayout; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; @@ -127,7 +127,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { // The GUI builder is using FlowLayout therefore this change so have no // impact on the initally designed layout. This change will just effect // how the components are laid out as size of the window changes. - buttonBarPanel.setLayout(new WrapLayout(java.awt.FlowLayout.LEFT)); + buttonBarPanel.setLayout(new WrapLayout()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index f604a6257e..83e04a9d1b 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -3,7 +3,7 @@
- + @@ -37,7 +37,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -93,73 +93,103 @@ - + - - + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + - - - - - + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + - - - - - - + @@ -202,7 +232,7 @@ - + @@ -365,7 +395,6 @@ - @@ -453,10 +482,10 @@ - - - - + + + + @@ -497,9 +526,9 @@ - - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index fb85efcf0c..acb6446c9d 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -31,7 +31,6 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** * Panel for configuring view preferences. @@ -180,12 +179,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentSessionSettingsPanel = new javax.swing.JPanel(); hideRejectedResultsCheckbox = new javax.swing.JCheckBox(); - setPreferredSize(new java.awt.Dimension(625, 465)); + setPreferredSize(new java.awt.Dimension(727, 495)); viewPreferencesScrollPane.setBorder(null); - viewPreferencesScrollPane.setPreferredSize(new java.awt.Dimension(625, 465)); + viewPreferencesScrollPane.setPreferredSize(new java.awt.Dimension(727, 493)); - viewPreferencesPanel.setPreferredSize(new java.awt.Dimension(625, 465)); + viewPreferencesPanel.setPreferredSize(new java.awt.Dimension(727, 492)); globalSettingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.globalSettingsPanel.border.title"))); // NOI18N @@ -267,7 +266,6 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { org.openide.awt.Mnemonics.setLocalizedText(scoColumnsLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.scoColumnsLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(scoColumnsCheckbox, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.scoColumnsCheckbox.text")); // NOI18N - scoColumnsCheckbox.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); scoColumnsCheckbox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { scoColumnsCheckboxActionPerformed(evt); @@ -310,53 +308,74 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addContainerGap() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(hideOtherUsersTagsCheckbox)) + .addComponent(maxResultsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(maxResultsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(325, 325, 325)) .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addComponent(scoColumnsLabel) - .addGap(135, 135, 135) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(hideOtherUsersTagsLabel) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hideKnownFilesLabel) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hideKnownFilesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(hideOtherUsersTagsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(77, 77, 77)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, globalSettingsPanelLayout.createSequentialGroup() + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(scoColumnsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, globalSettingsPanelLayout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(hideOtherUsersTagsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(99, 99, 99)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(32, 32, 32) + .addComponent(scoColumnsWrapAroundText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(93, 93, 93)) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideSlackCheckbox) - .addComponent(viewsHideSlackCheckbox))) - .addComponent(hideSlackFilesLabel)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourcesHideKnownCheckbox) - .addComponent(viewsHideKnownCheckbox)))) + .addComponent(scoColumnsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(14, 14, 14))) + .addGap(10, 10, 10)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, globalSettingsPanelLayout.createSequentialGroup() + .addComponent(hideSlackFilesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(51, 51, 51)) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) - .addComponent(scoColumnsCheckbox)) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addGap(32, 32, 32) - .addComponent(scoColumnsWrapAroundText))) - .addGap(18, 18, 18) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(dataSourcesHideSlackCheckbox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, globalSettingsPanelLayout.createSequentialGroup() + .addComponent(viewsHideKnownCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(103, 103, 103)) + .addComponent(dataSourcesHideKnownCheckbox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(viewsHideSlackCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(116, 116, 116))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(displayTimeLabel) - .addComponent(selectFileLabel) - .addComponent(translateTextLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(displayTimeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(91, 91, 91)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(translateTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(46, 46, 46)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addComponent(selectFileLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(90, 90, 90)) .addGroup(globalSettingsPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(fileNameTranslationColumnCheckbox) - .addComponent(keepCurrentViewerRadioButton) - .addComponent(useBestViewerRadioButton) - .addComponent(useLocalTimeRadioButton) - .addComponent(useAnotherTimeRadioButton))))) - .addGroup(globalSettingsPanelLayout.createSequentialGroup() - .addComponent(maxResultsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(maxResultsSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGap(24, 24, 24) + .addComponent(jScrollPane1)) + .addComponent(fileNameTranslationColumnCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(useAnotherTimeRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(globalSettingsPanelLayout.createSequentialGroup() + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(useLocalTimeRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(keepCurrentViewerRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(useBestViewerRadioButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(44, 44, 44))))))) + .addContainerGap()) ); globalSettingsPanelLayout.setVerticalGroup( globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -396,7 +415,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(useLocalTimeRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(useAnotherTimeRadioButton) + .addComponent(useAnotherTimeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -425,8 +444,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(currentCaseSettingsPanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(groupByDataSourceCheckbox) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(groupByDataSourceCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(474, 474, 474)) ); currentCaseSettingsPanelLayout.setVerticalGroup( currentCaseSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -450,8 +469,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(currentSessionSettingsPanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(hideRejectedResultsCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(hideRejectedResultsCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(418, 418, 418)) ); currentSessionSettingsPanelLayout.setVerticalGroup( currentSessionSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -480,7 +499,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addComponent(currentCaseSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(currentSessionSettingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(0, 0, 0)) ); viewPreferencesScrollPane.setViewportView(viewPreferencesPanel); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 15bc46a8da..c7ccf32099 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -260,7 +260,7 @@ public class BlackboardArtifactNode extends AbstractContentNode counts = new HashMap<>(); + + AccountTypeResults() { + update(); + } + + /** + * Given the type name of the Account.Type, provides the count of those type. + * @param accountType The type name of the Account.Type. + * @return The number of results found for the given account type. + */ + Long getCount(String accountType) { + return counts.get(accountType); + } + + /** + * Retrieves an alphabetically organized list of all the account types. + * @return An alphabetically organized list of all the account types. + */ + List getTypes() { + List types = new ArrayList<>(counts.keySet()); + Collections.sort(types); + return types; + } + + /** + * Queries the database and updates the counts for each account type. + */ + private void update() { + String accountTypesInUseQuery + = "SELECT blackboard_attributes.value_text as account_type, COUNT(*) as count " + + " FROM blackboard_artifacts " //NON-NLS + + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS + + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS + + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS + + getFilterByDataSourceClause() + + " GROUP BY blackboard_attributes.value_text "; + + try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery); + ResultSet resultSet = executeQuery.getResultSet()) { + + counts.clear(); + while (resultSet.next()) { + String accountType = resultSet.getString("account_type"); + Long count = resultSet.getLong("count"); + counts.put(accountType, count); + } + } catch (TskCoreException | SQLException ex) { + LOGGER.log(Level.SEVERE, "Error querying for account_types", ex); + } + } + } /** * Creates child nodes for each account type in the db. */ private class AccountTypeFactory extends ObservingChildren { - + /* * The pcl is in this class because it has the easiest mechanisms to add * and remove itself during its life cycles. @@ -281,6 +344,7 @@ final public class Accounts implements AutopsyVisitableItem { ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue(); if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID()) { + accountTypeResults.update(); reviewStatusBus.post(eventData); } } catch (NoCurrentCaseException notUsed) { @@ -324,37 +388,31 @@ final public class Accounts implements AutopsyVisitableItem { @Override protected boolean createKeys(List list) { - String accountTypesInUseQuery - = "SELECT DISTINCT blackboard_attributes.value_text as account_type " - + " FROM blackboard_artifacts " //NON-NLS - + " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS - + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS - + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS - + getFilterByDataSourceClause(); - - try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery); - ResultSet resultSet = executeQuery.getResultSet()) { - while (resultSet.next()) { - String accountType = resultSet.getString("account_type"); - list.add(accountType); - } - } catch (TskCoreException | SQLException ex) { - LOGGER.log(Level.SEVERE, "Error querying for account_types", ex); - } - + list.addAll(accountTypeResults.getTypes()); return true; } + + /** + * Registers the given node with the reviewStatusBus and returns + * the node wrapped in an array. + * @param node The node to be wrapped. + * @return The array containing this node. + */ + private Node[] getNodeArr(Node node) { + reviewStatusBus.register(node); + return new Node[]{node}; + } @Override protected Node[] createNodesForKey(String acountTypeName) { if (Account.Type.CREDIT_CARD.getTypeName().equals(acountTypeName)) { - return new Node[]{new CreditCardNumberAccountTypeNode()}; + return getNodeArr(new CreditCardNumberAccountTypeNode()); } else { try { Account.Type accountType = skCase.getCommunicationsManager().getAccountType(acountTypeName); - return new Node[]{new DefaultAccountTypeNode(accountType)}; + return getNodeArr(new DefaultAccountTypeNode(accountType)); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Error getting display name for account type. ", ex); } @@ -509,11 +567,14 @@ final public class Accounts implements AutopsyVisitableItem { * no special behavior. */ final public class DefaultAccountTypeNode extends DisplayableItemNode { - + private final Account.Type accountType; + private DefaultAccountTypeNode(Account.Type accountType) { super(Children.create(new DefaultAccountFactory(accountType), true), Lookups.singleton(accountType)); - setName(accountType.getDisplayName()); - this.setIconBaseWithExtension(getIconFilePath(accountType)); //NON-NLS + this.accountType = accountType; + String iconPath = getIconFilePath(accountType); + this.setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) == '/' ? iconPath.substring(1) : iconPath); //NON-NLS + updateName(); } @Override @@ -530,6 +591,24 @@ final public class Accounts implements AutopsyVisitableItem { public String getItemType() { return getClass().getName(); } + + + @Subscribe + void handleReviewStatusChange(ReviewStatusChangeEvent event) { + updateName(); + } + + @Subscribe + void handleDataAdded(ModuleDataEvent event) { + updateName(); + } + + /** + * Gets the latest counts for the account type and then updates the name. + */ + public void updateName() { + setName(String.format("%s (%d)", accountType.getDisplayName(), accountTypeResults.getCount(accountType.getTypeName()))); + } } /** @@ -659,6 +738,23 @@ final public class Accounts implements AutopsyVisitableItem { setName(Account.Type.CREDIT_CARD.getDisplayName()); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/credit-cards.png"); //NON-NLS } + + /** + * Gets the latest counts for the account type and then updates the name. + */ + public void updateName() { + setName(String.format("%s (%d)", Account.Type.CREDIT_CARD.getDisplayName(), accountTypeResults.getCount(Account.Type.CREDIT_CARD.getTypeName()))); + } + + @Subscribe + void handleReviewStatusChange(ReviewStatusChangeEvent event) { + updateName(); + } + + @Subscribe + void handleDataAdded(ModuleDataEvent event) { + updateName(); + } @Override public boolean isLeafTypeNode() { diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java index c9ad380a32..0a8f93fa92 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java @@ -34,8 +34,8 @@ final class DiscoveryUiUtils { private static final int ICON_SIZE = 16; private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png"; private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png"; - private static final String DELETE_ICON_PATH = "/org/sleuthkit/autopsy/images/file-icon-deleted.png"; - private static final String UNSUPPORTED_DOC_PATH = "/org/sleuthkit/autopsy/images/image-extraction-not-supported.png"; + private static final String DELETE_ICON_PATH = "org/sleuthkit/autopsy/images/file-icon-deleted.png"; + private static final String UNSUPPORTED_DOC_PATH = "org/sleuthkit/autopsy/images/image-extraction-not-supported.png"; private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false)); private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false)); private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false)); diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form index c7d9f2b4ee..09e12b5693 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.form @@ -21,7 +21,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -50,53 +50,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -118,6 +72,11 @@ + + + + + @@ -125,15 +84,20 @@ - + - + + + + + + @@ -155,74 +119,105 @@ + + + + + + - + - + + + + + + + - + - + + + + + + + + + + + + + + + - + - + + + + + + @@ -239,6 +234,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -282,7 +350,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 7a750f50eb..0acc2e1bf3 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -410,6 +410,7 @@ public class ResultsPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; javax.swing.JPanel pagingPanel = new javax.swing.JPanel(); previousPageButton = new javax.swing.JButton(); @@ -420,6 +421,10 @@ public class ResultsPanel extends javax.swing.JPanel { gotoPageField = new javax.swing.JTextField(); javax.swing.JLabel pageSizeLabel = new javax.swing.JLabel(); pageSizeComboBox = new javax.swing.JComboBox<>(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); javax.swing.JSplitPane resultsSplitPane = new javax.swing.JSplitPane(); javax.swing.JPanel instancesPanel = new javax.swing.JPanel(); javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane(); @@ -429,6 +434,7 @@ public class ResultsPanel extends javax.swing.JPanel { setPreferredSize(new java.awt.Dimension(777, 475)); pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + pagingPanel.setLayout(new java.awt.GridBagLayout()); previousPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N previousPageButton.setBorder(null); @@ -441,11 +447,26 @@ public class ResultsPanel extends javax.swing.JPanel { previousPageButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 12, 6, 0); + pagingPanel.add(previousPageButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(currentPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.currentPageLabel.text")); // NOI18N - currentPageLabel.setMaximumSize(new java.awt.Dimension(90, 23)); + currentPageLabel.setMaximumSize(new java.awt.Dimension(190, 23)); currentPageLabel.setMinimumSize(new java.awt.Dimension(90, 23)); - currentPageLabel.setPreferredSize(new java.awt.Dimension(90, 23)); + currentPageLabel.setPreferredSize(new java.awt.Dimension(100, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 14, 6, 0); + pagingPanel.add(currentPageLabel, gridBagConstraints); nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N nextPageButton.setBorder(null); @@ -458,28 +479,70 @@ public class ResultsPanel extends javax.swing.JPanel { nextPageButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 0, 6, 0); + pagingPanel.add(nextPageButton, gridBagConstraints); + pageControlsLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); org.openide.awt.Mnemonics.setLocalizedText(pageControlsLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageControlsLabel.text")); // NOI18N - pageControlsLabel.setMaximumSize(new java.awt.Dimension(33, 23)); + pageControlsLabel.setMaximumSize(new java.awt.Dimension(133, 23)); pageControlsLabel.setMinimumSize(new java.awt.Dimension(33, 23)); - pageControlsLabel.setPreferredSize(new java.awt.Dimension(33, 23)); + pageControlsLabel.setPreferredSize(new java.awt.Dimension(60, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; + gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0); + pagingPanel.add(pageControlsLabel, gridBagConstraints); + gotoPageLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); org.openide.awt.Mnemonics.setLocalizedText(gotoPageLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.gotoPageLabel.text")); // NOI18N - gotoPageLabel.setMaximumSize(new java.awt.Dimension(70, 23)); + gotoPageLabel.setMaximumSize(new java.awt.Dimension(170, 23)); gotoPageLabel.setMinimumSize(new java.awt.Dimension(70, 23)); - gotoPageLabel.setPreferredSize(new java.awt.Dimension(70, 23)); + gotoPageLabel.setPreferredSize(new java.awt.Dimension(100, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; + gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0); + pagingPanel.add(gotoPageLabel, gridBagConstraints); gotoPageField.setEnabled(false); + gotoPageField.setPreferredSize(new java.awt.Dimension(26, 22)); gotoPageField.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { gotoPageFieldActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 5, 0, 0); + pagingPanel.add(gotoPageField, gridBagConstraints); + pageSizeLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); org.openide.awt.Mnemonics.setLocalizedText(pageSizeLabel, org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.pageSizeLabel.text")); // NOI18N - pageSizeLabel.setMaximumSize(new java.awt.Dimension(60, 23)); + pageSizeLabel.setMaximumSize(new java.awt.Dimension(160, 23)); pageSizeLabel.setMinimumSize(new java.awt.Dimension(60, 23)); - pageSizeLabel.setPreferredSize(new java.awt.Dimension(60, 23)); + pageSizeLabel.setPreferredSize(new java.awt.Dimension(90, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 9; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST; + gridBagConstraints.insets = new java.awt.Insets(6, 18, 6, 0); + pagingPanel.add(pageSizeLabel, gridBagConstraints); pageSizeComboBox.setModel(new DefaultComboBoxModel(new Integer[] {25,50,75,100,125,150,175,200})); pageSizeComboBox.setSelectedIndex(3); @@ -488,47 +551,34 @@ public class ResultsPanel extends javax.swing.JPanel { pageSizeChanged(evt); } }); - - javax.swing.GroupLayout pagingPanelLayout = new javax.swing.GroupLayout(pagingPanel); - pagingPanel.setLayout(pagingPanelLayout); - pagingPanelLayout.setHorizontalGroup( - pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pagingPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .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) - .addGap(0, 0, 0) - .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) - .addComponent(gotoPageField, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(pageSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pageSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - pagingPanelLayout.setVerticalGroup( - pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pagingPanelLayout.createSequentialGroup() - .addGap(4, 4, 4) - .addGroup(pagingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .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) - .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) - .addComponent(gotoPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(gotoPageField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(4, 4, 4)) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 10; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 5, 0, 277); + pagingPanel.add(pageSizeComboBox, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 11; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 0.1; + pagingPanel.add(filler1, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + pagingPanel.add(filler2, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + pagingPanel.add(filler3, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + pagingPanel.add(filler4, gridBagConstraints); resultsSplitPane.setDividerLocation(380); resultsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); @@ -553,7 +603,7 @@ public class ResultsPanel extends javax.swing.JPanel { instancesPanel.setLayout(instancesPanelLayout); instancesPanelLayout.setHorizontalGroup( instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 775, Short.MAX_VALUE) + .addGap(0, 779, Short.MAX_VALUE) .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -576,7 +626,7 @@ public class ResultsPanel extends javax.swing.JPanel { 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(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( @@ -584,7 +634,7 @@ public class ResultsPanel extends javax.swing.JPanel { .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) - .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 436, Short.MAX_VALUE) .addGap(0, 0, 0)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java index bc56968f99..e923d6dbd6 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.logging.Level; +import javafx.util.Pair; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException; @@ -75,11 +76,11 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter * * @param mapWaypoints List of filtered MapWaypoints. */ - abstract void handleFilteredWaypointSet(Set mapWaypoints); + abstract void handleFilteredWaypointSet(Set mapWaypoints, List> tracks); @Override public void process(List waypoints) { - List tracks = null; + List tracks = new ArrayList<>(); if (filters.getArtifactTypes().contains(ARTIFACT_TYPE.TSK_GPS_TRACK)) { try { tracks = Track.getTracks(Case.getCurrentCase().getSleuthkitCase(), filters.getDataSources()); @@ -87,11 +88,15 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter logger.log(Level.WARNING, "Exception thrown while retrieving list of Tracks", ex); } } + Pair, List>> waypointsAndTracks = createWaypointList(waypoints, tracks); + + final Set pointSet = MapWaypoint.getWaypoints(waypointsAndTracks.getKey()); + final List> trackSets = new ArrayList<>(); + for (List t : waypointsAndTracks.getValue()) { + trackSets.add(MapWaypoint.getWaypoints(t)); + } - List completeList = createWaypointList(waypoints, tracks); - final Set pointSet = MapWaypoint.getWaypoints(completeList); - - handleFilteredWaypointSet(pointSet); + handleFilteredWaypointSet(pointSet, trackSets); } /** @@ -104,8 +109,9 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter * @return A list of waypoints including the tracks based on the current * filters. */ - private List createWaypointList(List waypoints, List tracks) { + private Pair, List>> createWaypointList(List waypoints, List tracks) { final List completeList = new ArrayList<>(); + List> filteredTracks = new ArrayList<>(); if (tracks != null) { Long timeRangeEnd; @@ -117,19 +123,22 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter timeRangeStart = timeRangeEnd - (86400 * filters.getMostRecentNumDays()); completeList.addAll(getWaypointsInRange(timeRangeStart, timeRangeEnd, waypoints)); - completeList.addAll(getTracksInRange(timeRangeStart, timeRangeEnd, tracks)); - + + filteredTracks = getTracksInRange(timeRangeStart, timeRangeEnd, tracks); + for (List filteredTrack : filteredTracks) { + completeList.addAll(filteredTrack); + } } else { completeList.addAll(waypoints); for (Track track : tracks) { completeList.addAll(track.getPath()); + filteredTracks.add(track.getPath()); } } } else { completeList.addAll(waypoints); } - - return completeList; + return new Pair<>(completeList, filteredTracks); } /** @@ -158,31 +167,30 @@ abstract class AbstractWaypointFetcher implements WaypointBuilder.WaypointFilter } /** - * Return a list of waypoints from the given tracks that fall into for - * tracks that fall into the given time range. The track start time will - * used for determining if the whole track falls into the range. + * Return a list of lists of waypoints from the given tracks that fall into + * the given time range. The track start time will used for determining if + * the whole track falls into the range. * * @param timeRangeStart start timestamp of range (seconds from java epoch) * @param timeRangeEnd start timestamp of range (seconds from java epoch) * @param tracks Track list. * - * @return A list of waypoints that that belong to tracks that fall into the - * time range. + * @return A list of lists of waypoints corresponding to belong to tracks + * that exist within the time range. */ - private List getTracksInRange(Long timeRangeStart, Long timeRangeEnd, List tracks) { - List completeList = new ArrayList<>(); + private List> getTracksInRange(Long timeRangeStart, Long timeRangeEnd, List tracks) { + List> ret = new ArrayList<>(); if (tracks != null) { for (Track track : tracks) { Long trackTime = track.getStartTime(); if ((trackTime == null && filters.showWaypointsWithoutTimeStamp()) || (trackTime != null && (trackTime >= timeRangeStart && trackTime <= timeRangeEnd))) { - - completeList.addAll(track.getPath()); + ret.add(track.getPath()); } } } - return completeList; + return ret; } /** diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java index da8e14a65b..ae387c7847 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java @@ -330,7 +330,7 @@ public final class GeolocationTopComponent extends TopComponent { * * @param waypointList */ - void addWaypointsToMap(Set waypointList) { + void addWaypointsToMap(Set waypointList, List> tracks) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -347,6 +347,8 @@ public final class GeolocationTopComponent extends TopComponent { } mapPanel.clearWaypoints(); mapPanel.setWaypoints(waypointList); + mapPanel.setTracks(tracks); + mapPanel.initializePainter(); setWaypointLoading(false); geoFilterPanel.setEnabled(true); } @@ -499,8 +501,8 @@ public final class GeolocationTopComponent extends TopComponent { } @Override - void handleFilteredWaypointSet(Set mapWaypoints) { - addWaypointsToMap(mapWaypoints); + void handleFilteredWaypointSet(Set mapWaypoints, List> tracks) { + addWaypointsToMap(mapWaypoints, tracks); } } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 46600f2c86..44de21ff81 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -19,11 +19,13 @@ package org.sleuthkit.autopsy.geolocation; import java.awt.AlphaComposite; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; @@ -71,6 +73,9 @@ import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException; import org.sleuthkit.datamodel.TskCoreException; import javax.imageio.ImageIO; import javax.swing.SwingUtilities; +import org.jxmapviewer.painter.CompoundPainter; +import org.jxmapviewer.painter.Painter; +import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; /** * The map panel. This panel contains the jxmapviewer MapViewer @@ -84,6 +89,7 @@ final public class MapPanel extends javax.swing.JPanel { private boolean zoomChanging; private KdTree waypointTree; private Set waypointSet; + private List> tracks = new ArrayList<>(); private Popup currentPopup; private final PopupFactory popupFactory; @@ -96,6 +102,7 @@ final public class MapPanel extends javax.swing.JPanel { private BufferedImage transparentWaypointImage; private MapWaypoint currentlySelectedWaypoint; + private Set currentlySelectedTrack; /** * Creates new form MapPanel @@ -204,6 +211,10 @@ final public class MapPanel extends javax.swing.JPanel { mapViewer.setCenterPosition(new GeoPosition(0, 0)); + initializePainter(); + } + + void initializePainter() { // Basic painters for the way points. WaypointPainter waypointPainter = new WaypointPainter() { @Override @@ -217,7 +228,12 @@ final public class MapPanel extends javax.swing.JPanel { }; waypointPainter.setRenderer(new MapWaypointRenderer()); - mapViewer.setOverlayPainter(waypointPainter); + ArrayList> painters = new ArrayList<>(); + painters.add(new MapTrackRenderer(tracks)); + painters.add(waypointPainter); + + CompoundPainter compoundPainter = new CompoundPainter<>(painters); + mapViewer.setOverlayPainter(compoundPainter); } /** @@ -306,6 +322,15 @@ final public class MapPanel extends javax.swing.JPanel { mapViewer.repaint(); } + /** + * Stores the given List of tracks from which to draw paths later + * + * @param tracks + */ + void setTracks(List> tracks) { + this.tracks = tracks; + } + /** * Set the current zoom level. * @@ -324,6 +349,7 @@ final public class MapPanel extends javax.swing.JPanel { void clearWaypoints() { waypointTree = null; currentlySelectedWaypoint = null; + currentlySelectedTrack = null; if (currentPopup != null) { currentPopup.hide(); } @@ -661,9 +687,17 @@ final public class MapPanel extends javax.swing.JPanel { if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt)) { List waypoints = findClosestWaypoint(evt.getPoint()); if (waypoints.size() > 0) { - currentlySelectedWaypoint = waypoints.get(0); + MapWaypoint selection = waypoints.get(0); + currentlySelectedWaypoint = selection; + for (Set track : tracks) { + if (track.contains(selection)) { + currentlySelectedTrack = track; + break; + } + } } else { currentlySelectedWaypoint = null; + currentlySelectedTrack = null; } showDetailsPopup(); } @@ -691,18 +725,18 @@ final public class MapPanel extends javax.swing.JPanel { */ private class MapWaypointRenderer implements WaypointRenderer { - private final Map imageCache = new HashMap<>(); + private final Map dotImageCache = new HashMap<>(); + private final Map waypointImageCache = new HashMap<>(); /** * - * @param waypoint the waypoint for which to get the color - * @param currentlySelectedWaypoint the waypoint that is currently - * selected + * @param waypoint the waypoint for which to get the color selected * @return the color that this waypoint should be rendered */ - private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) { + private Color getColor(MapWaypoint waypoint) { Color baseColor = waypoint.getColor(); - if (waypoint.equals(currentlySelectedWaypoint)) { + if (waypoint.equals(currentlySelectedWaypoint) + || (currentlySelectedTrack != null && currentlySelectedTrack.contains(waypoint))) { // Highlight this waypoint since it is selected return Color.YELLOW; } else { @@ -710,10 +744,32 @@ final public class MapPanel extends javax.swing.JPanel { } } + /** + * Creates a dot image with the specified color + * + * @param color the color of the new image + * @return the new dot image + */ + private BufferedImage createTrackDotImage(Color color) { + int w = 10; + int h = 10; + + BufferedImage ret = new BufferedImage(w + 2, h + 2, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = ret.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(color); + g.fillOval(1, 1, w, h); + g.setColor(Color.BLACK); + g.setStroke(new BasicStroke(1)); + g.drawOval(1, 1, w, h); + g.dispose(); + return ret; + } + /** * Creates a waypoint image with the specified color * - * @param color the color of the new waypoint image + * @param color the color of the new image * @return the new waypoint image */ private BufferedImage createWaypointImage(Color color) { @@ -723,6 +779,7 @@ final public class MapPanel extends javax.swing.JPanel { BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g = ret.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.drawImage(whiteWaypointImage, 0, 0, null); g.setComposite(AlphaComposite.SrcIn); g.setColor(color); @@ -734,22 +791,88 @@ final public class MapPanel extends javax.swing.JPanel { } @Override - public void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, MapWaypoint waypoint) { - Color color = getColor(waypoint, currentlySelectedWaypoint); - - // Store computed images in cache for later use - BufferedImage image = imageCache.computeIfAbsent(color, k -> { - return createWaypointImage(color); - }); - - Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom()); - + public void paintWaypoint(Graphics2D g, JXMapViewer map, MapWaypoint waypoint) { + Color color = getColor(waypoint); + BufferedImage image; + int artifactType = waypoint.getArtifactTypeID(); + Point2D point = map.getTileFactory().geoToPixel(waypoint.getPosition(), map.getZoom()); int x = (int) point.getX(); int y = (int) point.getY(); - gd = (Graphics2D) gd.create(); - gd.drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null); - gd.dispose(); + if (artifactType == ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID() + || artifactType == ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID() + || artifactType == ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) { + image = dotImageCache.computeIfAbsent(color, k -> { + return createTrackDotImage(color); + }); + // Center the dot on the GPS coordinate + y -= image.getHeight() / 2; + } else { + image = waypointImageCache.computeIfAbsent(color, k -> { + return createWaypointImage(color); + }); + // Align the bottom of the pin with the GPS coordinate + y -= image.getHeight(); + } + // Center image horizontally on image + x -= image.getWidth() / 2; + + Graphics2D g2d = (Graphics2D) g.create(); + g2d.drawImage(image, x, y, null); + g2d.dispose(); + } + } + + /** + * Renderer for map track routes + */ + private class MapTrackRenderer implements Painter { + + private final List> tracks; + + MapTrackRenderer(List> tracks) { + this.tracks = tracks; + } + + private void drawRoute(Set track, Graphics2D g, JXMapViewer map) { + int lastX = 0; + int lastY = 0; + + boolean first = true; + + for (MapWaypoint wp : track) { + Point2D p = map.getTileFactory().geoToPixel(wp.getPosition(), map.getZoom()); + int thisX = (int) p.getX(); + int thisY = (int) p.getY(); + + if (first) { + first = false; + } else { + g.drawLine(lastX, lastY, thisX, thisY); + } + + lastX = thisX; + lastY = thisY; + } + } + + @Override + public void paint(Graphics2D g, JXMapViewer map, int w, int h) { + Graphics2D g2d = (Graphics2D) g.create(); + + Rectangle bounds = map.getViewportBounds(); + g2d.translate(-bounds.x, -bounds.y); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(Color.BLACK); + g2d.setStroke(new BasicStroke(2)); + + for (Set track : tracks) { + drawRoute(track, g2d, map); + } + + g2d.dispose(); } } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index f9e4ed86ee..f7673338b1 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -84,7 +84,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private final GeoPosition position; /** - * Returns a list of of MapWaypoint objects for the given list of + * Returns a list of MapWaypoint objects for the given list of * datamodel.Waypoint objects. * * @param dmWaypoints @@ -199,6 +199,13 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe return getFormattedDetails(dataModelWaypoint); } + /** + * Returns the artifact type for this waypoint's data source + */ + int getArtifactTypeID() { + return dataModelWaypoint.getArtifact().getArtifactTypeID(); + } + /** * Returns a list of JMenuItems for the waypoint. The list list may contain * nulls which should be removed or replaced with JSeparators. diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java index 1f8f25452e..11ff0107dd 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java @@ -98,7 +98,7 @@ public final class WaypointBuilder { * * @param wwaypoints This of waypoints. */ - void process(List wwaypoints); + void process(List waypoints); } /** diff --git a/Core/src/org/sleuthkit/autopsy/guiutils/WrapLayout.java b/Core/src/org/sleuthkit/autopsy/guiutils/WrapLayout.java new file mode 100644 index 0000000000..d43df6a39e --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/guiutils/WrapLayout.java @@ -0,0 +1,642 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.guiutils; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +/** + * A wrap layout, similar to flow layout, orders subcomponents in a horizontal + * row similar to words in a paragraph. When subcomponents are moved to a new + * row, the height of the target component is expanded to accomodate. This + * layout also accomodates simultaneously left-aligned and right-aligned + * components. + * + * Inspired by Rob Camick's WrapLayout + * https://tips4java.wordpress.com/2008/11/06/wrap-layout/ and FlowLayout + * https://raw.githubusercontent.com/mynawang/Java8-Source-Code/master/src/main/jdk8/java/awt/FlowLayout.java. + */ +public class WrapLayout implements LayoutManager, java.io.Serializable { + + private static final long serialVersionUID = 1L; + + /** + * The horizontal gap will specify the spacing between neighboring + * subcomponents as well as the spacing between subcomponents and the + * borders of the target component. + * + * @see #getHorizontalGap() + * @see #setHorizontalGap(int) + */ + private int horizontalGap = 0; + + /** + * The vertical gap between neighboring rows as well as the spacing between + * rows and the borders of the target component. + * + * @see #getVerticalGap() + * @see #setVerticalGap(int) + */ + private int verticalGap = 0; + + /** + * If true, subcomponents will be aligned on their bottom edge. Otherwise, + * subcomponents are aligned on their top edge. + */ + private boolean alignOnBaseline = false; + + /** + * The set of components that will be aligned on the opposite side. If the + * target component's orientation is left to right, this set of components + * will be right aligned. + */ + private final Set oppositeAlignedItems = new HashSet<>(); + + /** + * Constructs a new WrapLayout with a default 5-unit horizontal + * and vertical gap. + */ + public WrapLayout() { + this(5, 5); + } + + /** + * Constructs a new WrapLayout. + * + * @param verticalGap The vertical gap spacing between rows of + * subcomponents as well as the spacing between the + * target component and rows. + * @param horizontalGap The horizontal gap spacing between neighboring + * subcomponents as well as the spacing between the + * subcomponents and the target component's border. + */ + public WrapLayout(int verticalGap, int horizontalGap) { + this.verticalGap = verticalGap; + this.horizontalGap = horizontalGap; + } + + /** + * Sets the set of components that will be aligned on the opposite side. If + * the target component's orientation is left to right, this set of + * components will be right aligned. + * + * @param oppAlignedComponents The components that will be aligned on the + * opposite side. + */ + public void setOppositeAligned(Collection oppAlignedComponents) { + this.oppositeAlignedItems.clear(); + this.oppositeAlignedItems.addAll(oppAlignedComponents); + } + + /** + * Retrieves the set of components that will be aligned on the opposite + * side. If the target component's orientation is left to right, this set of + * components will be right aligned. + * + * @return The components that will be aligned on the opposite side. + */ + public Collection getOppositeAlignedItems() { + return Collections.unmodifiableCollection(oppositeAlignedItems); + } + + /** + * Retrieves the horizontal gap between neighboring subcomponents as well as + * the spacing between subcomponents and the borders of the target + * component. + * + * @return The horizontal gap between components and between the components + * and the borders of the Container. + */ + public int getHorizontalGap() { + return horizontalGap; + } + + /** + * Sets the horizontal gap between neighboring subcomponents as well as the + * spacing between subcomponents and the borders of the target component. + * + * @param horizontalGap The horizontal gap between components and between + * the components and the borders of the + * Container. + */ + public void setHorizontalGap(int horizontalGap) { + this.horizontalGap = horizontalGap; + } + + /** + * Retrieves the vertical gap between neighboring rows as well as the + * spacing between rows and the borders of the target component. + * + * @return The vertical gap between components and between the components + * and the borders of the Container. + */ + public int getVerticalGap() { + return verticalGap; + } + + /** + * Sets the vertical gap between neighboring rows as well as the spacing + * between rows and the borders of the target component. + * + * @param verticalGap The vertical gap between components and between the + * components and the borders of the + * Container. + */ + public void setVerticalGap(int verticalGap) { + this.verticalGap = verticalGap; + } + + /** + * Sets whether or not subcomponents should be vertically aligned along + * their bottom edge. Otherwise, subcomponents are aligned on their top + * edge. The default is false. + * + * @param alignOnBaseline Whether or not components should be vertically + * aligned on their bottom edge. + */ + public void setAlignOnBaseline(boolean alignOnBaseline) { + this.alignOnBaseline = alignOnBaseline; + } + + /** + * Returns true if components are to be vertically aligned along their + * bottom edge. Otherwise, subcomponents are aligned on their top edge. The + * default is false. + * + * @return If components are to be vertically aligned along their bottom + * edge. + */ + public boolean isAlignOnBaseline() { + return alignOnBaseline; + } + + /** + * Adds the specified component to the layout. Not used by this class. NOTE: + * This method is not used by this layout. + * + * @param name The name of the component. + * @param comp The component to be added. + */ + @Override + public void addLayoutComponent(String name, Component comp) { + //Empty + } + + /** + * Removes the specified component from the layout. Not used by this class. + * NOTE: This method is not used by this layout. + * + * @param comp The component to remove. + */ + @Override + public void removeLayoutComponent(Component comp) { + //Empty + } + + /** + * Determines the subcomponent's y position. + * + * @param rowY The top y position of the row. + * @param alignBaseline Whether this component should be aligned on the + * baseline. + * @param rowHeight The height of the row. + * @param itemHeight The height of the item. + * + * @return The top y position of the component. + */ + private int getComponentY(int rowY, boolean alignBaseline, int rowHeight, + int itemHeight) { + return alignBaseline + ? rowY + rowHeight - itemHeight + : rowY; + } + + /** + * * Determines the subcomponent's x position. + * + * @param leftX The leftmost position a component can be placed. + * @param rightX The rightmost position a component can be placed. + * @param ltr If the components should be laid out left to right. + * @param xPos The x position of the component (if left to right, + * how far from leftX; otherwise how far from rightX). + * @param componentWidth The component's width. + * + * @return The component's left x position. + */ + private int getComponentX(int leftX, int rightX, boolean ltr, int xPos, + int componentWidth) { + return ltr ? leftX + xPos : rightX - xPos - componentWidth; + } + + /** + * Sets a subcomponent's size to preferred size and sets the (x,y) position + * for the component. + * + * @param comp The component. + * @param alignBaseline Whether this component should be aligned on the + * baseline. + * @param ltr If the components should be laid out left to right. + * @param rowY The top y position of the row. + * @param rowHeight The height of the row. + * @param leftX The leftmost position a component can be placed. + * @param rightX The rightmost position a component can be placed. + * @param xPos The x position of the component (if left to right, + * how far from leftX; otherwise how far from rightX). + * + * @return The width of the component. + */ + private int setComponentDims(Component comp, boolean alignBaseline, + boolean ltr, int rowY, int rowHeight, int leftX, int rightX, + int xPos) { + + Dimension d = comp.getPreferredSize(); + comp.setSize(d); + + int x = getComponentX(leftX, rightX, ltr, xPos, d.width); + int y = getComponentY(rowY, alignBaseline, rowHeight, d.height); + comp.setLocation(x, y); + + return d.width; + } + + @Override + public void layoutContainer(Container target) { + ParentDimensions targetDims = getTargetDimensions(target); + List components = Arrays.asList(target.getComponents()); + List rows = getAllRows(components, true, targetDims.getInnerWidth()); + + boolean ltr = target.getComponentOrientation().isLeftToRight(); + boolean useBaseline = isAlignOnBaseline(); + + int rowY = targetDims.getInsets().top + getVerticalGap(); + int leftX = targetDims.getInsets().left + getHorizontalGap(); + int rightX = targetDims.getOuterWidth() - targetDims.getInsets().right - getHorizontalGap(); + + for (WrapLayoutRow row : rows) { + int rowHeight = row.getHeight(); + + int curX = 0; + if (row.getComponents() != null) { + for (Component origComp : row.getComponents()) { + curX += setComponentDims(origComp, useBaseline, ltr, rowY, rowHeight, leftX, rightX, curX) + getHorizontalGap(); + } + } + + if (row.getOppositeAligned() != null) { + curX = 0; + // reverse opposite aligned for layout purposes since flipping ltr + Collections.reverse(row.getOppositeAligned()); + for (Component oppAlignedComp : row.getOppositeAligned()) { + curX += setComponentDims(oppAlignedComp, useBaseline, !ltr, rowY, rowHeight, leftX, rightX, curX) + getHorizontalGap(); + } + } + + rowY += rowHeight + getVerticalGap(); + } + } + + @Override + public Dimension preferredLayoutSize(Container target) { + return layoutSize(target, true); + } + + @Override + public Dimension minimumLayoutSize(Container target) { + Dimension minimum = layoutSize(target, false); + minimum.width -= (getHorizontalGap() + 1); + return minimum; + } + + /** + * This class provides metrics on the parent container dimensions. + */ + private static class ParentDimensions { + + private final int outerWidth; + private final int innerWidth; + private final Insets insets; + + /** + * Main constructor for ParentDimensions class. + * + * @param outerWidth The full width that the component can consume. + * @param innerWidth The full width that subcomponent rows can consume. + * @param insets The insets of the parent container. + */ + ParentDimensions(int outerWidth, int innerWidth, Insets insets) { + this.outerWidth = outerWidth; + this.innerWidth = innerWidth; + this.insets = insets; + } + + /** + * Gets the full width that the component can consume. + * + * @return The full width that the component can consume. + */ + int getOuterWidth() { + return outerWidth; + } + + /** + * Gets the full width that subcomponent rows can consume. This is the + * outerWidth accounting for left and right insets. + * + * @return The full width that subcomponent rows can consume. + */ + int getInnerWidth() { + return innerWidth; + } + + /** + * Gets the insets of the parent container. + * + * @return The insets of the parent container. + */ + Insets getInsets() { + return insets; + } + } + + /** + * Derives metrics on the space allowed within the parent container for rows + * of components. + * + * @param target The target container. + * + * @return The dimensions for laying out components. + */ + private ParentDimensions getTargetDimensions(Container target) { + Container container = target; + + while (container.getSize().width == 0 && container.getParent() != null) { + container = container.getParent(); + } + + int targetWidth = container.getSize().width; + + if (targetWidth == 0) { + targetWidth = Integer.MAX_VALUE; + } + + Insets insets = container.getInsets(); + int horizontalInsetsAndGap = insets.left + insets.right + (getHorizontalGap() * 2); + int maxWidth = targetWidth - horizontalInsetsAndGap; + + return new ParentDimensions(targetWidth, maxWidth, insets); + } + + /** + * Returns the minimum or preferred dimension needed to layout the target + * container. + * + * @param target Target to get layout size for. + * @param preferred Should preferred size be calculated. + * + * @return The dimension to layout the target container. + */ + private Dimension layoutSize(Container target, boolean preferred) { + ParentDimensions targetDims = getTargetDimensions(target); + List components = Arrays.asList(target.getComponents()); + List rows = getAllRows(components, preferred, targetDims.getInnerWidth()); + + Integer containerHeight = rows.stream().map((r) -> r.getHeight()).reduce(0, Integer::sum); + // add in vertical gap between rows + if (rows.size() > 1) { + containerHeight += (rows.size() - 1) * getVerticalGap(); + } + + containerHeight += targetDims.getInsets().top + targetDims.getInsets().bottom; + + Integer containerWidth = rows.stream().map((r) -> r.getWidth()).reduce(0, Math::max); + containerWidth += targetDims.getInsets().left + targetDims.getInsets().right + (getHorizontalGap() * 2); + + // When using a scroll pane or the DecoratedLookAndFeel we need to + // make sure the preferred size is less than the size of the + // target containter so shrinking the container size works + // correctly. Removing the horizontal gap is an easy way to do this. + Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target); + + if (scrollPane != null && target.isValid()) { + containerWidth -= (getHorizontalGap() + 1); + } + + return new Dimension(containerWidth, containerHeight); + } + + /** + * A row of components in the WrapLayout. + */ + private class WrapLayoutRow { + + private final List components; + private final List oppositeAligned; + private final int height; + private final int width; + + /** + * This is the main constructor for a row of components in the + * WrapLayout. + * + * @param components The components that should be normally aligned + * in the row. + * @param oppositeAligned The components that should be oppositely + * aligned in the row. + * @param height The maximum height of the row. + * @param width The total width of the row. + */ + WrapLayoutRow(List components, List oppositeAligned, + int height, int width) { + this.components = components; + this.oppositeAligned = oppositeAligned; + this.height = height; + this.width = width; + } + + /** + * Gets the normally aligned components in the order that they will be + * laid out. + * + * @return The normally aligned components in the order that they will + * be laid out. + */ + List getComponents() { + return components; + } + + /** + * Gets the opposite aligned components in the order that they will be + * laid out. + * + * @return The opposite aligned components in the order that they will + * be laid out. + */ + List getOppositeAligned() { + return oppositeAligned; + } + + /** + * Gets the minimum height of the row which is the maximum of the + * preferred heights of the components. + * + * @return The minimum height of the row which is the maximum of the + * preferred heights of the components. + */ + int getHeight() { + return height; + } + + /** + * Gets the minimum width of the row which is the sum of the preferred + * widths of the subcomponents. + * + * @return The minimum width of the row which is the sum of the + * preferred widths of the subcomponents. + */ + int getWidth() { + return width; + } + + } + + /** + * Retrieves the rows of wrap layout components. + * + * @param components The components to be laid out. + * @param preferred Whether or not to use preferred dimensions of + * subcomponents for determining rows. + * @param maxWidth The maximum width that a row can consume. + * + * @return The list of rows ordered from top to bottom. + */ + private List getAllRows(List components, + boolean preferred, int maxWidth) { + List originalComp + = components + .stream() + .filter((comp) -> !this.oppositeAlignedItems.contains(comp)) + .collect(Collectors.toList()); + + List originalRowSet = getRowSet(originalComp, preferred, maxWidth); + + List oppositeAlignedComp + = components + .stream() + .filter((comp) -> this.oppositeAlignedItems.contains(comp)) + .collect(Collectors.toList()); + + // go in reverse order and then revert so we can use same getRowSet method + Collections.reverse(oppositeAlignedComp); + List oppositeRowSet = getRowSet(oppositeAlignedComp, preferred, maxWidth) + .stream() + .map((WrapLayoutRow row) -> { + Collections.reverse(row.getComponents()); + return new WrapLayoutRow(null, row.getComponents(), row.getHeight(), row.getWidth()); + }) + .collect(Collectors.toList()); + Collections.reverse(oppositeRowSet); + + List toReturn = new ArrayList<>(); + + // if there is a row of components that will have both normal and opposite aligned + // components, create the corresponding row. + if (!originalRowSet.isEmpty() && !oppositeRowSet.isEmpty()) { + WrapLayoutRow lastOrig = originalRowSet.get(originalRowSet.size() - 1); + WrapLayoutRow firstOpp = oppositeRowSet.get(0); + + int proposedRowWidth = lastOrig.getWidth() + firstOpp.getWidth() + getHorizontalGap(); + if (proposedRowWidth <= maxWidth) { + WrapLayoutRow middleRow = new WrapLayoutRow(lastOrig.getComponents(), firstOpp.getOppositeAligned(), + Math.max(lastOrig.getHeight(), firstOpp.getHeight()), proposedRowWidth); + + toReturn.addAll(originalRowSet.subList(0, originalRowSet.size() - 1)); + toReturn.add(middleRow); + toReturn.addAll(oppositeRowSet.subList(1, oppositeRowSet.size())); + return toReturn; + } + } + + toReturn.addAll(originalRowSet); + toReturn.addAll(oppositeRowSet); + return toReturn; + } + + /** + * Handles determining rows for a single set of similarly aligned + * components. Used once for normal alignment and once for opposite aligned + * components. + * + * @param components The components in the set of similarly aligned items. + * @param preferred Whether or not to use preferred dimensions for + * components. + * @param maxWidth The maximum width components can consume. + * + * @return The list of rows determined. + */ + private List getRowSet(List components, + boolean preferred, int maxWidth) { + List rows = new ArrayList<>(); + + List rowComponents = new ArrayList<>(); + int rowWidth = 0; + int rowHeight = 0; + + for (Component m : components) { + if (m.isVisible()) { + Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize(); + + // Can't add the component to current row. Start a new row. + if (rowWidth + d.width > maxWidth) { + rows.add(new WrapLayoutRow(rowComponents, null, rowHeight, rowWidth)); + rowComponents = new ArrayList<>(); + rowWidth = 0; + rowHeight = 0; + } + + // Add a horizontal gap for all components after the first + if (rowWidth != 0) { + rowWidth += getHorizontalGap(); + } + + rowComponents.add(m); + rowWidth += d.width; + rowHeight = Math.max(rowHeight, d.height); + } + } + + if (!rowComponents.isEmpty()) { + rows.add(new WrapLayoutRow(rowComponents, null, rowHeight, rowWidth)); + } + + return rows; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.form index a981e39826..9d613f0cf7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.form @@ -21,15 +21,15 @@ - + - - + + - + - + @@ -39,32 +39,23 @@ - - + + - + - + - - - - - - - - - - + @@ -86,5 +77,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.java index 57e6cb8577..2c83297673 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/dataSourceIntegrity/DataSourceIntegrityIngestSettingsPanel.java @@ -1,7 +1,7 @@ /* * Central Repository * - * Copyright 2018 Basis Technology Corp. + * Copyright 2018-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,7 @@ final class DataSourceIntegrityIngestSettingsPanel extends IngestModuleIngestJob /** * Creates new form DataSourceIntegrityIngestSettingsPanel */ - public DataSourceIntegrityIngestSettingsPanel(DataSourceIntegrityIngestSettings settings) { + DataSourceIntegrityIngestSettingsPanel(DataSourceIntegrityIngestSettings settings) { initComponents(); customizeComponents(settings); } @@ -58,40 +58,70 @@ final class DataSourceIntegrityIngestSettingsPanel extends IngestModuleIngestJob @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; - computeHashesCheckbox = new javax.swing.JCheckBox(); verifyHashesCheckbox = new javax.swing.JCheckBox(); ingestSettingsLabel = new javax.swing.JLabel(); noteLabel = new javax.swing.JLabel(); + computeHashesPanel = new javax.swing.JPanel(); + computeHashesCheckbox = new javax.swing.JCheckBox(); + computeHashesTextArea = new javax.swing.JTextArea(); setPreferredSize(new java.awt.Dimension(300, 155)); - org.openide.awt.Mnemonics.setLocalizedText(computeHashesCheckbox, org.openide.util.NbBundle.getMessage(DataSourceIntegrityIngestSettingsPanel.class, "DataSourceIntegrityIngestSettingsPanel.computeHashesCheckbox.text")); // NOI18N - computeHashesCheckbox.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - computeHashesCheckboxActionPerformed(evt); - } - }); - org.openide.awt.Mnemonics.setLocalizedText(verifyHashesCheckbox, org.openide.util.NbBundle.getMessage(DataSourceIntegrityIngestSettingsPanel.class, "DataSourceIntegrityIngestSettingsPanel.verifyHashesCheckbox.text")); // NOI18N + verifyHashesCheckbox.setFocusable(false); ingestSettingsLabel.setFont(ingestSettingsLabel.getFont().deriveFont(ingestSettingsLabel.getFont().getStyle() | java.awt.Font.BOLD)); org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(DataSourceIntegrityIngestSettingsPanel.class, "DataSourceIntegrityIngestSettingsPanel.ingestSettingsLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(noteLabel, org.openide.util.NbBundle.getMessage(DataSourceIntegrityIngestSettingsPanel.class, "DataSourceIntegrityIngestSettingsPanel.noteLabel.text")); // NOI18N + computeHashesPanel.setLayout(new java.awt.GridBagLayout()); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + computeHashesPanel.add(computeHashesCheckbox, gridBagConstraints); + + computeHashesTextArea.setEditable(false); + computeHashesTextArea.setBackground(new java.awt.Color(240, 240, 240)); + computeHashesTextArea.setColumns(20); + computeHashesTextArea.setLineWrap(true); + computeHashesTextArea.setRows(2); + computeHashesTextArea.setText(org.openide.util.NbBundle.getMessage(DataSourceIntegrityIngestSettingsPanel.class, "DataSourceIntegrityIngestSettingsPanel.computeHashesCheckbox.text")); // NOI18N + computeHashesTextArea.setWrapStyleWord(true); + computeHashesTextArea.setBorder(null); + computeHashesTextArea.setFocusable(false); + computeHashesTextArea.setOpaque(false); + computeHashesTextArea.setRequestFocusEnabled(false); + computeHashesTextArea.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + computeHashesTextAreaMouseClicked(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(3, 0, 0, 0); + computeHashesPanel.add(computeHashesTextArea, gridBagConstraints); + 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(noteLabel) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(noteLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(verifyHashesCheckbox) - .addComponent(computeHashesCheckbox) - .addComponent(ingestSettingsLabel)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(ingestSettingsLabel) + .addComponent(computeHashesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(13, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -99,21 +129,23 @@ final class DataSourceIntegrityIngestSettingsPanel extends IngestModuleIngestJob .addContainerGap() .addComponent(ingestSettingsLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(computeHashesCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(computeHashesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(verifyHashesCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(18, 18, 18) .addComponent(noteLabel) - .addContainerGap(53, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents - private void computeHashesCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_computeHashesCheckboxActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_computeHashesCheckboxActionPerformed + private void computeHashesTextAreaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_computeHashesTextAreaMouseClicked + computeHashesCheckbox.doClick(); + }//GEN-LAST:event_computeHashesTextAreaMouseClicked // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox computeHashesCheckbox; + private javax.swing.JPanel computeHashesPanel; + private javax.swing.JTextArea computeHashesTextArea; private javax.swing.JLabel ingestSettingsLabel; private javax.swing.JLabel noteLabel; private javax.swing.JCheckBox verifyHashesCheckbox; diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeDialog.java index 2c6b7322f9..b387ba7d40 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -50,7 +50,7 @@ class AddFileTypeDialog extends JDialog { } private static final long serialVersionUID = 1L; - private static final Dimension BUTTON_SIZE = new Dimension(65, 23); + private static final Dimension BUTTON_SIZE = new Dimension(85, 23); private FileType fileType; final private AddFileTypePanel addMimeTypePanel; private BUTTON_PRESSED result; @@ -61,9 +61,10 @@ class AddFileTypeDialog extends JDialog { * Creates a dialog for creating a file type */ @Messages({"AddMimeTypedialog.title=File Type"}) - AddFileTypeDialog() { + AddFileTypeDialog() { super(WindowManager.getDefault().getMainWindow(), Bundle.AddMimeTypedialog_title(), true); addMimeTypePanel = new AddFileTypePanel(); + init(); } /** @@ -74,23 +75,18 @@ class AddFileTypeDialog extends JDialog { AddFileTypeDialog(FileType fileType) { super(WindowManager.getDefault().getMainWindow(), Bundle.AddMimeTypedialog_title(), true); addMimeTypePanel = new AddFileTypePanel(fileType); + init(); } /** - * Displays the add file type dialog. - * + * Do initialization of dialog components. */ - @NbBundle.Messages({ + @NbBundle.Messages({ "AddMimeTypeDialog.addButton.title=OK", "AddMimeTypeDialog.cancelButton.title=Cancel"}) - void display() { + private void init() { setLayout(new BorderLayout()); - /** - * Center the dialog. - */ - setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - /** * Get the default or saved ingest job settings for this context and use * them to create and add an ingest job settings panel. @@ -120,15 +116,15 @@ class AddFileTypeDialog extends JDialog { //setting both max and preffered size appears to be necessary to change the button size cancelButton.setMaximumSize(BUTTON_SIZE); cancelButton.setPreferredSize(BUTTON_SIZE); - + // Put the buttons in their own panel, under the settings panel. JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); - buttonPanel.add(okButton); - buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 35), new Dimension(10, 35), new Dimension(10, 35))); buttonPanel.add(cancelButton); - buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 35), new Dimension(10, 35), new Dimension(10, 35))); + buttonPanel.validate(); add(buttonPanel, BorderLayout.LINE_END); /** @@ -150,13 +146,23 @@ class AddFileTypeDialog extends JDialog { } }); enableOkButton(); + setResizable(false); + pack(); + } + + /** + * Displays the add file type dialog. + * + */ + void display() { + /** + * Center the dialog. + */ + setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); /** * Show the dialog. */ - pack(); - setResizable(false); setVisible(true); - } /** diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.form index 325270ea0b..7dce458862 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.form @@ -47,7 +47,7 @@ - + @@ -85,7 +85,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.java index c00363bc56..f7f1da8755 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -312,7 +312,7 @@ class AddFileTypePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1) .addComponent(postHitCheckBox)) - .addGap(0, 0, Short.MAX_VALUE)) + .addGap(0, 0, 0)) .addGroup(layout.createSequentialGroup() .addGap(71, 71, 71) .addComponent(mimeFormatLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) @@ -342,7 +342,7 @@ class AddFileTypePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(setNameLabel) .addComponent(setNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); }//
//GEN-END:initComponents @@ -350,6 +350,7 @@ class AddFileTypePanel extends javax.swing.JPanel { if (evt.getSource().equals(this.editSigButton) && this.signatureList.getSelectedValue() != null) { int selected = this.signatureList.getSelectedIndex(); this.addSigDialog = new AddFileTypeSignatureDialog(this.signatureList.getSelectedValue()); + this.addSigDialog.display(false); if (addSigDialog.getResult() == BUTTON_PRESSED.OK) { signaturesListModel.removeElementAt(selected); this.signaturesListModel.add(selected, this.addSigDialog.getSignature()); @@ -370,6 +371,7 @@ class AddFileTypePanel extends javax.swing.JPanel { private void addSigButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addSigButtonActionPerformed if (evt.getSource().equals(this.addSigButton)) { this.addSigDialog = new AddFileTypeSignatureDialog(); + this.addSigDialog.display(true); if (addSigDialog.getResult() == AddFileTypeSignatureDialog.BUTTON_PRESSED.OK) { signaturesListModel.addElement(this.addSigDialog.getSignature()); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java index 770d97ff87..c8f10e4e36 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignatureDialog.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,7 +42,7 @@ import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; final class AddFileTypeSignatureDialog extends JDialog { private static final long serialVersionUID = 1L; - private static final Dimension BUTTON_SIZE = new Dimension(65, 23); + private static final Dimension BUTTON_SIZE = new Dimension(85, 23); private final AddFileTypeSignaturePanel addFileTypeSigPanel; private static final String TITLE = NbBundle.getMessage(RunIngestModulesAction.class, "RunIngestModulesAction.name"); private Signature signature; @@ -63,7 +63,7 @@ final class AddFileTypeSignatureDialog extends JDialog { AddFileTypeSignatureDialog() { super(WindowManager.getDefault().getMainWindow(), TITLE, true); this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(); - this.display(true); + init(); } /** @@ -74,43 +74,12 @@ final class AddFileTypeSignatureDialog extends JDialog { AddFileTypeSignatureDialog(Signature toEdit) { super(WindowManager.getDefault().getMainWindow(), TITLE, true); this.addFileTypeSigPanel = new AddFileTypeSignaturePanel(toEdit); - this.display(false); + init(); } - /** - * Gets the signature that was created by this dialog. - * - * @return the signature. - */ - public Signature getSignature() { - return signature; - } - - /** - * Gets which button was pressed (OK or Cancel). - * - * @return The result. - */ - public BUTTON_PRESSED getResult() { - return result; - } - - /** - * Displays the add signature dialog. - * - * @param add Whether or not this is an edit or a new window. - */ - @Messages({ - "AddFileTypeSignatureDialog.addButton.title=OK", - "AddFileTypeSignatureDialog.cancelButton.title=Cancel"}) - void display(boolean add) { + private void init() { setLayout(new BorderLayout()); - /** - * Center the dialog. - */ - setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); - /** * Get the default or saved ingest job settings for this context and use * them to create and add an ingest job settings panel. @@ -141,14 +110,15 @@ final class AddFileTypeSignatureDialog extends JDialog { //setting both max and preffered size appears to be necessary to change the button size cancelButton.setMaximumSize(BUTTON_SIZE); cancelButton.setPreferredSize(BUTTON_SIZE); - + // Put the buttons in their own panel, under the settings panel. JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); buttonPanel.add(okButton); - buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 35), new Dimension(10, 35), new Dimension(10, 35))); buttonPanel.add(cancelButton); - buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10))); + buttonPanel.add(new javax.swing.Box.Filler(new Dimension(10, 35), new Dimension(10, 35), new Dimension(10, 35))); + buttonPanel.validate(); add(buttonPanel, BorderLayout.LINE_END); /** @@ -161,12 +131,44 @@ final class AddFileTypeSignatureDialog extends JDialog { doButtonAction(false); } }); + setResizable(false); + pack(); + } + /** + * Gets the signature that was created by this dialog. + * + * @return the signature. + */ + public Signature getSignature() { + return signature; + } + + /** + * Gets which button was pressed (OK or Cancel). + * + * @return The result. + */ + public BUTTON_PRESSED getResult() { + return result; + } + + /** + * Displays the add signature dialog. + * + * @param add Whether or not this is an edit or a new window. + */ + @Messages({ + "AddFileTypeSignatureDialog.addButton.title=OK", + "AddFileTypeSignatureDialog.cancelButton.title=Cancel"}) + void display(boolean add) { + /** + * Center the dialog. + */ + setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); /** * Show the dialog. */ - pack(); - setResizable(false); setVisible(true); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form index f61fb16aae..1dddd44b1d 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.form @@ -72,7 +72,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java index 6be6a71fe0..88c181c0fa 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/AddFileTypeSignaturePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -283,7 +283,7 @@ class AddFileTypeSignaturePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(offsetRelativeToLabel)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); }//
//GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java index 04f5e49a1e..f58adbfc0d 100644 --- a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java +++ b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java @@ -56,7 +56,7 @@ public final class JythonModuleLoader { * @return A list of objects that implement the IngestModuleFactory * interface. */ - public static List getIngestModuleFactories() { + public static synchronized List getIngestModuleFactories() { return getInterfaceImplementations(new IngestModuleFactoryDefFilter(), IngestModuleFactory.class); } @@ -66,7 +66,7 @@ public final class JythonModuleLoader { * @return A list of objects that implement the GeneralReportModule * interface. */ - public static List getGeneralReportModules() { + public static synchronized List getGeneralReportModules() { return getInterfaceImplementations(new GeneralReportModuleDefFilter(), GeneralReportModule.class); } @Messages({"JythonModuleLoader.pythonInterpreterError.title=Python Modules", diff --git a/Core/src/org/sleuthkit/autopsy/textextractors/TextFileExtractor.java b/Core/src/org/sleuthkit/autopsy/textextractors/TextFileExtractor.java index 4a89b74d3c..9c71b14ecc 100644 --- a/Core/src/org/sleuthkit/autopsy/textextractors/TextFileExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/textextractors/TextFileExtractor.java @@ -25,8 +25,10 @@ import java.io.Reader; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.logging.Level; +import org.apache.commons.lang.StringUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.textutils.EncodingUtils; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.ReadContentInputStream; import org.sleuthkit.datamodel.TskCoreException; @@ -38,6 +40,7 @@ public final class TextFileExtractor implements TextExtractor { private static final Logger logger = Logger.getLogger(TextFileExtractor.class.getName()); private final AbstractFile file; + private static final String PLAIN_TEXT_MIME_TYPE = "text/plain"; private Charset encoding = null; @@ -73,7 +76,22 @@ public final class TextFileExtractor implements TextExtractor { } @Override - public boolean isSupported() { - return file.getMIMEType().equals("text/plain"); + public boolean isSupported() { + // get the MIME type + String mimeType = file.getMIMEType(); + + // if it is not present, attempt to use the FileTypeDetector to determine + if (StringUtils.isEmpty(mimeType)) { + FileTypeDetector fileTypeDetector = null; + try { + fileTypeDetector = new FileTypeDetector(); + } catch (FileTypeDetector.FileTypeDetectorInitException ex) { + logger.log(Level.SEVERE, "Unable to create file type detector for determining MIME type", ex); + return false; + } + mimeType = fileTypeDetector.getMIMEType(file); + } + + return PLAIN_TEXT_MIME_TYPE.equals(mimeType); } } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.form index 08f7946452..18cd9b97af 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.form @@ -11,90 +11,28 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -105,6 +43,11 @@ + + + + + @@ -115,6 +58,11 @@ + + + + + @@ -122,6 +70,11 @@ + + + + + @@ -136,13 +89,29 @@ + + + + + + + + + + + + + + + + @@ -150,6 +119,11 @@ + + + + + @@ -157,20 +131,41 @@ + + + + + + + + + + + + + + + + + + + + + @@ -180,10 +175,18 @@ + + + + + + + + @@ -195,14 +198,38 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java index 5b34605403..621aec9d2a 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -127,6 +127,7 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; authenticationKeyField = new javax.swing.JTextField(); warningLabel = new javax.swing.JLabel(); @@ -140,11 +141,33 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { authenticationKeyLabel = new javax.swing.JLabel(); instructionsScrollPane = new javax.swing.JScrollPane(); instructionsTextArea = new javax.swing.JTextArea(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + + setLayout(new java.awt.GridBagLayout()); authenticationKeyField.setToolTipText(org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.authenticationKeyField.toolTipText")); // NOI18N + authenticationKeyField.setMaximumSize(new java.awt.Dimension(800, 22)); + authenticationKeyField.setPreferredSize(new java.awt.Dimension(163, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(14, 5, 0, 12); + add(authenticationKeyField, gridBagConstraints); warningLabel.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.warningLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(7, 12, 6, 0); + add(warningLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(testButton, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.testButton.text")); // NOI18N testButton.addActionListener(new java.awt.event.ActionListener() { @@ -152,8 +175,23 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { testButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 12, 0, 0); + add(testButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(targetLanguageLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.targetLanguageLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 12, 0, 0); + add(targetLanguageLabel, gridBagConstraints); targetLanguageComboBox.setEnabled(false); targetLanguageComboBox.addItemListener(new java.awt.event.ItemListener() { @@ -161,88 +199,99 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { targetLanguageComboBoxSelected(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(8, 5, 0, 0); + add(targetLanguageComboBox, gridBagConstraints); testUntranslatedTextField.setText(DEFUALT_TEST_STRING); + testUntranslatedTextField.setMinimumSize(new java.awt.Dimension(160, 22)); + testUntranslatedTextField.setPreferredSize(new java.awt.Dimension(160, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(8, 5, 0, 0); + add(testUntranslatedTextField, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(untranslatedLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.untranslatedLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 5, 0, 0); + add(untranslatedLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.resultLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); + add(resultLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(testResultValueLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.testResultValueLabel.text")); // NOI18N + testResultValueLabel.setMaximumSize(new java.awt.Dimension(600, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(4, 7, 0, 12); + add(testResultValueLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(authenticationKeyLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.authenticationKeyLabel.text")); // NOI18N + authenticationKeyLabel.setMaximumSize(new java.awt.Dimension(200, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(16, 12, 0, 0); + add(authenticationKeyLabel, gridBagConstraints); instructionsScrollPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); instructionsScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + instructionsScrollPane.setPreferredSize(new java.awt.Dimension(168, 80)); instructionsTextArea.setEditable(false); instructionsTextArea.setBackground(new java.awt.Color(240, 240, 240)); instructionsTextArea.setColumns(20); instructionsTextArea.setLineWrap(true); - instructionsTextArea.setRows(2); + instructionsTextArea.setRows(4); instructionsTextArea.setText(org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.instructionsTextArea.text")); // NOI18N instructionsTextArea.setWrapStyleWord(true); + instructionsTextArea.setCaretPosition(0); + instructionsTextArea.setMaximumSize(new java.awt.Dimension(1000, 200)); + instructionsTextArea.setPreferredSize(new java.awt.Dimension(164, 78)); instructionsScrollPane.setViewportView(instructionsTextArea); - 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(instructionsScrollPane) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(layout.createSequentialGroup() - .addComponent(authenticationKeyLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(authenticationKeyField, javax.swing.GroupLayout.PREFERRED_SIZE, 486, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(targetLanguageLabel) - .addComponent(testButton, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(untranslatedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(resultLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testResultValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addComponent(targetLanguageComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(276, 276, 276))))) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(instructionsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(authenticationKeyField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(authenticationKeyLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(targetLanguageLabel) - .addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(testButton) - .addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(untranslatedLabel) - .addComponent(resultLabel) - .addComponent(testResultValueLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(13, 12, 0, 0); + add(instructionsScrollPane, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 10; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 0.6; + add(filler1, gridBagConstraints); }// //GEN-END:initComponents @Messages({"BingTranslatorSettingsPanel.warning.invalidKey=Invalid translation authentication key"}) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.form index 33fca620d1..67bf16ebf9 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.form @@ -11,116 +11,63 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + @@ -132,6 +79,11 @@ + + + + + @@ -139,6 +91,15 @@ + + + + + + + + + @@ -149,13 +110,26 @@ + + + + + + + + + + + + + @@ -164,6 +138,11 @@ + + + + + @@ -172,6 +151,11 @@ + + + + + @@ -179,7 +163,18 @@ + + + + + + + + + + + @@ -191,6 +186,11 @@ + + + + + @@ -204,6 +204,11 @@ + + + + + @@ -215,14 +220,38 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java index 9244ba3b86..b9c6b852b1 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -184,12 +184,13 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; - credentialsLabel = new javax.swing.JLabel(); + javax.swing.JLabel credentialsLabel = new javax.swing.JLabel(); credentialsPathField = new javax.swing.JTextField(); browseButton = new javax.swing.JButton(); targetLanguageComboBox = new javax.swing.JComboBox<>(); - targetLanguageLabel = new javax.swing.JLabel(); + javax.swing.JLabel targetLanguageLabel = new javax.swing.JLabel(); warningLabel = new javax.swing.JLabel(); testResultValueLabel = new javax.swing.JLabel(); resultLabel = new javax.swing.JLabel(); @@ -198,40 +199,121 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { testButton = new javax.swing.JButton(); instructionsScrollPane = new javax.swing.JScrollPane(); instructionsTextArea = new javax.swing.JTextArea(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + + setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(credentialsLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.credentialsLabel.text")); // NOI18N + credentialsLabel.setMaximumSize(new java.awt.Dimension(200, 16)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(17, 12, 0, 0); + add(credentialsLabel, gridBagConstraints); credentialsPathField.setEditable(false); - credentialsPathField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - credentialsPathFieldActionPerformed(evt); - } - }); + credentialsPathField.setMaximumSize(new java.awt.Dimension(700, 22)); + credentialsPathField.setPreferredSize(new java.awt.Dimension(100, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(14, 7, 0, 0); + add(credentialsPathField, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.browseButton.text")); // NOI18N + browseButton.setMaximumSize(new java.awt.Dimension(100, 25)); browseButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { browseButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 9; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(13, 7, 0, 0); + add(browseButton, gridBagConstraints); targetLanguageComboBox.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(13, 7, 0, 0); + add(targetLanguageComboBox, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(targetLanguageLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.targetLanguageLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(16, 12, 0, 0); + add(targetLanguageLabel, gridBagConstraints); warningLabel.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.warningLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(13, 12, 6, 0); + add(warningLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(testResultValueLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.testResultValueLabel.text")); // NOI18N + testResultValueLabel.setMaximumSize(new java.awt.Dimension(600, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 7, 0, 0); + add(testResultValueLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.resultLabel.text")); // NOI18N resultLabel.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 5, 0, 0); + add(resultLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(untranslatedLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.untranslatedLabel.text")); // NOI18N untranslatedLabel.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 7, 0, 0); + add(untranslatedLabel, gridBagConstraints); testUntranslatedTextField.setText(DEFUALT_TEST_STRING); testUntranslatedTextField.setEnabled(false); + testUntranslatedTextField.setMinimumSize(new java.awt.Dimension(160, 22)); + testUntranslatedTextField.setPreferredSize(new java.awt.Dimension(160, 22)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(8, 5, 0, 0); + add(testUntranslatedTextField, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(testButton, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.testButton.text")); // NOI18N testButton.setEnabled(false); @@ -240,6 +322,13 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { testButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 12, 0, 0); + add(testButton, gridBagConstraints); instructionsScrollPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); instructionsScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); @@ -248,76 +337,31 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { instructionsTextArea.setBackground(new java.awt.Color(240, 240, 240)); instructionsTextArea.setColumns(20); instructionsTextArea.setLineWrap(true); - instructionsTextArea.setRows(2); + instructionsTextArea.setRows(4); instructionsTextArea.setText(org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.instructionsTextArea.text")); // NOI18N instructionsTextArea.setWrapStyleWord(true); + instructionsTextArea.setCaretPosition(0); + instructionsTextArea.setMaximumSize(new java.awt.Dimension(1000, 200)); + instructionsTextArea.setPreferredSize(new java.awt.Dimension(164, 78)); instructionsScrollPane.setViewportView(instructionsTextArea); - 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) - .addGroup(layout.createSequentialGroup() - .addComponent(instructionsScrollPane) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(testButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(credentialsLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(targetLanguageLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(credentialsPathField) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseButton) - .addGap(14, 14, 14)) - .addGroup(layout.createSequentialGroup() - .addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 317, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)))) - .addGroup(layout.createSequentialGroup() - .addGap(7, 7, 7) - .addComponent(untranslatedLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(resultLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(testResultValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(instructionsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(credentialsLabel) - .addComponent(credentialsPathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(browseButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(targetLanguageLabel) - .addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(testButton) - .addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(untranslatedLabel) - .addComponent(resultLabel) - .addComponent(testResultValueLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(13, 12, 0, 0); + add(instructionsScrollPane, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 10; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridheight = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 0.6; + add(filler1, gridBagConstraints); }// //GEN-END:initComponents @Messages({"GoogleTranslatorSettingsPanel.json.description=JSON Files", @@ -357,19 +401,13 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { } }//GEN-LAST:event_testButtonActionPerformed - private void credentialsPathFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_credentialsPathFieldActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_credentialsPathFieldActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton browseButton; - private javax.swing.JLabel credentialsLabel; private javax.swing.JTextField credentialsPathField; private javax.swing.JScrollPane instructionsScrollPane; private javax.swing.JTextArea instructionsTextArea; private javax.swing.JLabel resultLabel; private javax.swing.JComboBox targetLanguageComboBox; - private javax.swing.JLabel targetLanguageLabel; private javax.swing.JButton testButton; private javax.swing.JLabel testResultValueLabel; private javax.swing.JTextField testUntranslatedTextField; @@ -378,26 +416,28 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { // End of variables declaration//GEN-END:variables /** - * Get the currently selected target language code + * Get the currently selected target language code. * - * @return the target language code of the language selected in the combobox + * @return The target language code of the language selected in the combo + * box. */ String getTargetLanguageCode() { return targetLanguageCode; } /** - * Get the currently set path to the JSON credentials file + * Get the currently set path to the JSON credentials file. * - * @return the path to the credentials file specified in the textarea + * @return The path to the credentials file specified in the credentials + * field. */ String getCredentialsPath() { return credentialsPathField.getText(); } /** - * Listener to identfy when a combo box item has been selected and update - * the combo box to reflect that + * Listener to identify when a combo box item has been selected and update + * the combo box to reflect that selection. */ private class ComboBoxSelectionListener implements ItemListener { diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/Bundle.properties index ac480ca0e1..6ae7ed7d12 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/Bundle.properties @@ -4,3 +4,4 @@ TranslationContentPanel.ocrLabel.text=OCR: TranslationOptionsPanelController.moduleErr=Module Error TranslationOptionsPanelController.moduleErr.msg=A module caused an error listening to TranslationSettingsPanelController updates. See log to determine which module. Some data could be incomplete. TranslationContentPanel.showLabel.text=Show: +TranslationContentPanel.jSepLarge1.AccessibleContext.accessibleName= diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.form b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.form index 1b66a2ae6b..4dabce0985 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.form @@ -6,11 +6,11 @@ - + - + @@ -24,24 +24,20 @@ - + - + - - - - - - + - - + + + @@ -49,85 +45,208 @@ - + + + + - + - - + + - - - - + - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -136,8 +255,11 @@ + + + - + @@ -149,4 +271,4 @@ - \ No newline at end of file + diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.java index 340dc830d8..4f6fbd7271 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/ui/TranslationContentPanel.java @@ -25,11 +25,13 @@ import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.swing.JComboBox; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.corecomponents.AutoWrappingJTextPane; +import org.sleuthkit.autopsy.guiutils.WrapLayout; /** * A JPanel used by TranslatedContentViewer to display machine translation of @@ -49,6 +51,7 @@ public class TranslationContentPanel extends javax.swing.JPanel { */ public TranslationContentPanel() { initComponents(); + additionalInitComponents(); DISPLAY_PANE = new AutoWrappingJTextPane(); DISPLAY_PANE.setEditable(false); @@ -255,6 +258,13 @@ public class TranslationContentPanel extends javax.swing.JPanel { LANGUAGE_NAMES = createLanguageBiMap(); } + private void additionalInitComponents() { + // use wrap layout for better component wrapping + WrapLayout layout = new WrapLayout(0,5); + layout.setOppositeAligned(Arrays.asList(showPanel, ocrPanel)); + controlPanel.setLayout(layout); + } + /** * Selection choices to be displayed in the combobox dropdown. */ @@ -284,90 +294,117 @@ public class TranslationContentPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; - jPanel1 = new javax.swing.JPanel(); - displayTextComboBox = new javax.swing.JComboBox<>(); - ocrDropdown = new javax.swing.JComboBox<>(); - ocrLabel = new javax.swing.JLabel(); + controlPanel = new javax.swing.JPanel(); + javax.swing.JPanel warningLabelPanel = new javax.swing.JPanel(); warningLabel = new javax.swing.JLabel(); + jSeparator1 = new javax.swing.JSeparator(); + showPanel = new javax.swing.JPanel(); showLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed1 = new javax.swing.JSeparator(); + displayTextComboBox = new javax.swing.JComboBox<>(); + ocrPanel = new javax.swing.JPanel(); + javax.swing.JSeparator jSepLarge1 = new javax.swing.JSeparator(); + ocrLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSepMed2 = new javax.swing.JSeparator(); + ocrDropdown = new javax.swing.JComboBox<>(); textScrollPane = new javax.swing.JScrollPane(); setMaximumSize(new java.awt.Dimension(2000, 2000)); - setMinimumSize(new java.awt.Dimension(2, 2)); + setMinimumSize(new java.awt.Dimension(250, 2)); setName(""); // NOI18N - setPreferredSize(new java.awt.Dimension(100, 58)); + setPreferredSize(new java.awt.Dimension(250, 58)); setVerifyInputWhenFocusTarget(false); setLayout(new java.awt.BorderLayout()); - jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - jPanel1.setMaximumSize(new java.awt.Dimension(182, 24)); - jPanel1.setPreferredSize(new java.awt.Dimension(182, 24)); - jPanel1.setLayout(new java.awt.GridBagLayout()); + controlPanel.setMaximumSize(new java.awt.Dimension(20000, 20000)); + controlPanel.setMinimumSize(new java.awt.Dimension(2, 25)); + controlPanel.setName(""); // NOI18N + controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 0)); - displayTextComboBox.setMinimumSize(new java.awt.Dimension(43, 20)); - displayTextComboBox.setPreferredSize(new java.awt.Dimension(43, 20)); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 3; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.weightx = 0.1; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); - jPanel1.add(displayTextComboBox, gridBagConstraints); + warningLabelPanel.setMaximumSize(new java.awt.Dimension(32767, 25)); + warningLabelPanel.setMinimumSize(new java.awt.Dimension(2, 25)); + warningLabelPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); - ocrDropdown.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "N/A" })); - ocrDropdown.setEnabled(false); - ocrDropdown.setName(""); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 5; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.weightx = 0.1; - gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); - jPanel1.add(ocrDropdown, gridBagConstraints); + warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N + warningLabel.setMaximumSize(new java.awt.Dimension(250, 25)); + warningLabel.setMinimumSize(new java.awt.Dimension(150, 25)); + warningLabel.setPreferredSize(null); + warningLabelPanel.add(warningLabel); + + jSeparator1.setMaximumSize(new java.awt.Dimension(1, 25)); + jSeparator1.setMinimumSize(new java.awt.Dimension(1, 25)); + jSeparator1.setPreferredSize(new java.awt.Dimension(1, 25)); + warningLabelPanel.add(jSeparator1); + + controlPanel.add(warningLabelPanel); + + showPanel.setMaximumSize(new java.awt.Dimension(32767, 25)); + showPanel.setMinimumSize(new java.awt.Dimension(0, 25)); + showPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); + + org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(TranslationContentPanel.class, "TranslationContentPanel.showLabel.text")); // NOI18N + showLabel.setMaximumSize(new java.awt.Dimension(42, 25)); + showLabel.setMinimumSize(new java.awt.Dimension(42, 25)); + showLabel.setPreferredSize(null); + showPanel.add(showLabel); + + jSepMed1.setPreferredSize(new java.awt.Dimension(5, 0)); + showPanel.add(jSepMed1); + + displayTextComboBox.setMaximumSize(new java.awt.Dimension(170, 25)); + displayTextComboBox.setMinimumSize(new java.awt.Dimension(170, 25)); + displayTextComboBox.setPreferredSize(new java.awt.Dimension(170, 25)); + showPanel.add(displayTextComboBox); + + controlPanel.add(showPanel); + + ocrPanel.setMaximumSize(new java.awt.Dimension(32767, 25)); + ocrPanel.setMinimumSize(new java.awt.Dimension(0, 25)); + ocrPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); + + jSepLarge1.setPreferredSize(new java.awt.Dimension(10, 0)); + ocrPanel.add(jSepLarge1); + jSepLarge1.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(TranslationContentPanel.class, "TranslationContentPanel.jSepLarge1.AccessibleContext.accessibleName")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(ocrLabel, org.openide.util.NbBundle.getMessage(TranslationContentPanel.class, "TranslationContentPanel.ocrLabel.text")); // NOI18N ocrLabel.setEnabled(false); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 4; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); - jPanel1.add(ocrLabel, gridBagConstraints); + ocrLabel.setMaximumSize(new java.awt.Dimension(40, 25)); + ocrLabel.setMinimumSize(new java.awt.Dimension(25, 16)); + ocrLabel.setPreferredSize(null); + ocrPanel.add(ocrLabel); - warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/warning16.png"))); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; - gridBagConstraints.weightx = 0.25; - jPanel1.add(warningLabel, gridBagConstraints); + jSepMed2.setPreferredSize(new java.awt.Dimension(5, 0)); + ocrPanel.add(jSepMed2); - org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(TranslationContentPanel.class, "TranslationContentPanel.showLabel.text")); // NOI18N - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 2; - gridBagConstraints.gridy = 0; - jPanel1.add(showLabel, gridBagConstraints); + ocrDropdown.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "N/A" })); + ocrDropdown.setEnabled(false); + ocrDropdown.setMaximumSize(new java.awt.Dimension(170, 25)); + ocrDropdown.setMinimumSize(new java.awt.Dimension(170, 25)); + ocrDropdown.setName(""); // NOI18N + ocrDropdown.setPreferredSize(new java.awt.Dimension(170, 25)); + ocrPanel.add(ocrDropdown); - add(jPanel1, java.awt.BorderLayout.NORTH); + controlPanel.add(ocrPanel); + + add(controlPanel, java.awt.BorderLayout.NORTH); textScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); textScrollPane.setMaximumSize(new java.awt.Dimension(20000, 20000)); - textScrollPane.setPreferredSize(new java.awt.Dimension(640, 250)); + textScrollPane.setMinimumSize(new java.awt.Dimension(20, 20)); + textScrollPane.setPreferredSize(new java.awt.Dimension(20, 20)); add(textScrollPane, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel controlPanel; private javax.swing.JComboBox displayTextComboBox; - private javax.swing.JPanel jPanel1; + private javax.swing.JSeparator jSeparator1; private javax.swing.JComboBox ocrDropdown; private javax.swing.JLabel ocrLabel; + private javax.swing.JPanel ocrPanel; private javax.swing.JLabel showLabel; + private javax.swing.JPanel showPanel; private javax.swing.JScrollPane textScrollPane; private javax.swing.JLabel warningLabel; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/uicomponents/WrapLayout.java b/Core/src/org/sleuthkit/autopsy/uicomponents/WrapLayout.java deleted file mode 100755 index 5daf8d5646..0000000000 --- a/Core/src/org/sleuthkit/autopsy/uicomponents/WrapLayout.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2019 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.uicomponents; - -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Insets; -import javax.swing.JScrollPane; -import javax.swing.SwingUtilities; - -/** -* FlowLayout subclass that fully supports wrapping of components. -* -* Originally written by Rob Camick -* https://tips4java.wordpress.com/2008/11/06/wrap-layout/ -*/ -public class WrapLayout extends FlowLayout { - - private static final long serialVersionUID = 1L; - /** - * Constructs a new WrapLayout with a left alignment and a - * default 5-unit horizontal and vertical gap. - */ - public WrapLayout() { - super(); - } - - /** - * Constructs a new FlowLayout with the specified alignment - * and a default 5-unit horizontal and vertical gap. The value of the - * alignment argument must be one of WrapLayout, - * WrapLayout, or WrapLayout. - * - * @param align the alignment value - */ - public WrapLayout(int align) { - super(align); - } - - /** - * Creates a new flow layout manager with the indicated alignment and - * the indicated horizontal and vertical gaps. - *

- * The value of the alignment argument must be one of - * WrapLayout, WrapLayout, or - * WrapLayout. - * - * @param align the alignment value - * @param hgap the horizontal gap between components - * @param vgap the vertical gap between components - */ - public WrapLayout(int align, int hgap, int vgap) { - super(align, hgap, vgap); - } - - /** - * Returns the preferred dimensions for this layout given the - * visible components in the specified target container. - * - * @param target the component which needs to be laid out - * - * @return the preferred dimensions to lay out the subcomponents of the - * specified container - */ - @Override - public Dimension preferredLayoutSize(Container target) { - return layoutSize(target, true); - } - - /** - * Returns the minimum dimensions needed to layout the visible - * components contained in the specified target container. - * - * @param target the component which needs to be laid out - * - * @return the minimum dimensions to lay out the subcomponents of the - * specified container - */ - @Override - public Dimension minimumLayoutSize(Container target) { - Dimension minimum = layoutSize(target, false); - minimum.width -= (getHgap() + 1); - return minimum; - } - - /** - * Returns the minimum or preferred dimension needed to layout the - * target container. - * - * @param target target to get layout size for - * @param preferred should preferred size be calculated - * - * @return the dimension to layout the target container - */ - private Dimension layoutSize(Container target, boolean preferred) { - synchronized (target.getTreeLock()) { - // Each row must fit with the width allocated to the containter. - // When the container width = 0, the preferred width of the container - // has not yet been calculated so lets ask for the maximum. - - int targetWidth = target.getSize().width; - Container container = target; - - while (container.getSize().width == 0 && container.getParent() != null) { - container = container.getParent(); - } - - targetWidth = container.getSize().width; - - if (targetWidth == 0) { - targetWidth = Integer.MAX_VALUE; - } - - int hgap = getHgap(); - int vgap = getVgap(); - Insets insets = target.getInsets(); - int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2); - int maxWidth = targetWidth - horizontalInsetsAndGap; - - // Fit components into the allowed width - Dimension dim = new Dimension(0, 0); - int rowWidth = 0; - int rowHeight = 0; - - int nmembers = target.getComponentCount(); - - for (int i = 0; i < nmembers; i++) { - Component m = target.getComponent(i); - - if (m.isVisible()) { - Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize(); - - // Can't add the component to current row. Start a new row. - if (rowWidth + d.width > maxWidth) { - addRow(dim, rowWidth, rowHeight); - rowWidth = 0; - rowHeight = 0; - } - - // Add a horizontal gap for all components after the first - if (rowWidth != 0) { - rowWidth += hgap; - } - - rowWidth += d.width; - rowHeight = Math.max(rowHeight, d.height); - } - } - - addRow(dim, rowWidth, rowHeight); - - dim.width += horizontalInsetsAndGap; - dim.height += insets.top + insets.bottom + vgap * 2; - - // When using a scroll pane or the DecoratedLookAndFeel we need to - // make sure the preferred size is less than the size of the - // target containter so shrinking the container size works - // correctly. Removing the horizontal gap is an easy way to do this. - Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target); - - if (scrollPane != null && target.isValid()) { - dim.width -= (hgap + 1); - } - - return dim; - } - } - - /* - * A new row has been completed. Use the dimensions of this row to - * update the preferred size for the container. - * - * @param dim update the width and height when appropriate @param - * rowWidth the width of the row to add @param rowHeight the height of - * the row to add - */ - private void addRow(Dimension dim, int rowWidth, int rowHeight) { - dim.width = Math.max(dim.width, rowWidth); - - if (dim.height > 0) { - dim.height += getVgap(); - } - - dim.height += rowHeight; - } - } \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties index f3081bef89..2b25c96245 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties @@ -257,3 +257,8 @@ CasesDashboardTopComponent.refreshButton.text=Refresh AutoIngestCasesDeletionDialog.jLabel1.text=Progress CasesDashboardTopComponent.deleteOrphanCaseNodesButton.text=Delete Orphan Case Znodes CasesDashboardTopComponent.deleteOrphanManifestNodesButton.text=Delete Orphan Manifest Znodes +DeleteOrphanCaseNodesDialog.descriptionText.text=The following cases have orphaned znodes. Would you like to delete them? +DeleteOrphanCaseNodesDialog.okButton.text=OK +DeleteOrphanCaseNodesDialog.cancelButton.text=Cancel +DeleteOrphanCaseNodesDialog.titleText.text=Delete The Following Znodes? +DeleteOrphanCaseNodesDialog.lblNodeCount.text= diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index 46c6d587fc..adb7693b48 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -89,10 +89,6 @@ AutoIngestControlPanel.runningTable.toolTipText=The Running table displays the c AutoIngestControlPanel.SharedConfigurationDisabled=Shared configuration disabled AutoIngestControlPanel.ShowLogFailed.Message=Case log file does not exist AutoIngestControlPanel.ShowLogFailed.Title=Unable to display case log -# {0} - case db status -# {1} - search svc Status -# {2} - coord svc Status -# {3} - msg broker status AutoIngestControlPanel.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3} AutoIngestControlPanel.tbServicesStatusMessage.Message.Down=down AutoIngestControlPanel.tbServicesStatusMessage.Message.Unknown=unknown @@ -186,25 +182,23 @@ DeleteCaseTask.progress.acquiringManifestLocks=Acquiring exclusive manifest file DeleteCaseTask.progress.connectingToCoordSvc=Connecting to the coordination service... DeleteCaseTask.progress.deletingCaseDirCoordSvcNode=Deleting case directory znode... DeleteCaseTask.progress.deletingCaseNameCoordSvcNode=Deleting case name znode... -# {0} - data source path DeleteCaseTask.progress.deletingDataSource=Deleting data source {0}... DeleteCaseTask.progress.deletingJobLogLockNode=Deleting case auto ingest log znode... -# {0} - manifest file path DeleteCaseTask.progress.deletingManifest=Deleting manifest file {0}... -# {0} - manifest file path DeleteCaseTask.progress.deletingManifestFileNode=Deleting the manifest file znode for {0}... DeleteCaseTask.progress.deletingResourcesLockNode=Deleting case resources znode... DeleteCaseTask.progress.gettingManifestPaths=Getting manifest file paths... -# {0} - manifest file path DeleteCaseTask.progress.lockingManifest=Locking manifest file {0}... DeleteCaseTask.progress.openingCaseDatabase=Opening the case database... DeleteCaseTask.progress.openingCaseMetadataFile=Opening case metadata file... -# {0} - manifest file path DeleteCaseTask.progress.parsingManifest=Parsing manifest file {0}... -# {0} - manifest file path DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}... DeleteCaseTask.progress.startMessage=Starting deletion... DeleteOrphanCaseNodesAction.progressDisplayName=Cleanup Case Znodes +# {0} - item count +DeleteOrphanCaseNodesDialog.additionalInit.lblNodeCount.text=Znodes found: {0} +# {0} - item count +DeleteOrphanCaseNodesDialog.additionalInit.znodesTextArea.countMessage=ZNODES FOUND: {0} DeleteOrphanCaseNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service # {0} - node path DeleteOrphanCaseNodesTask.progress.deletingOrphanedCaseNode=Deleting orphaned case znode {0} @@ -213,7 +207,6 @@ DeleteOrphanCaseNodesTask.progress.lookingForOrphanedCaseZnodes=Looking for orph DeleteOrphanCaseNodesTask.progress.startMessage=Starting orphaned case znode cleanup DeleteOrphanManifestNodesAction.progressDisplayName=Cleanup Manifest File Znodes DeleteOrphanManifestNodesTask.progress.connectingToCoordSvc=Connecting to the coordination service -# {0} - node path DeleteOrphanManifestNodesTask.progress.deletingOrphanedManifestNode=Deleting orphaned manifest file znode {0} DeleteOrphanManifestNodesTask.progress.gettingManifestNodes=Querying the coordination service for manifest file znodes DeleteOrphanManifestNodesTask.progress.lookingForOrphanedManifestFileZnodes=Looking for orphaned manifest file znodes @@ -222,7 +215,6 @@ HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-use OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted. OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details. OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File -# {0} - caseErrorMessage OpenCaseAction.errorMsg=Failed to open case: {0} OpenCaseAction.menuItemText=Open OpenIDE-Module-Long-Description=This module contains features that are being developed by Basis Technology and are not part of the default Autopsy distribution. You can enable this module to use the new features. The features should be stable, but their exact behavior and API are subject to change.\n\nWe make no guarantee that the API of this module will not change, so developers should be careful when relying on it. @@ -456,3 +448,8 @@ CasesDashboardTopComponent.refreshButton.text=Refresh AutoIngestCasesDeletionDialog.jLabel1.text=Progress CasesDashboardTopComponent.deleteOrphanCaseNodesButton.text=Delete Orphan Case Znodes CasesDashboardTopComponent.deleteOrphanManifestNodesButton.text=Delete Orphan Manifest Znodes +DeleteOrphanCaseNodesDialog.descriptionText.text=The following cases have orphaned znodes. Would you like to delete them? +DeleteOrphanCaseNodesDialog.okButton.text=OK +DeleteOrphanCaseNodesDialog.cancelButton.text=Cancel +DeleteOrphanCaseNodesDialog.titleText.text=Delete The Following Znodes? +DeleteOrphanCaseNodesDialog.lblNodeCount.text= diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.form new file mode 100644 index 0000000000..8b314a48d7 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.form @@ -0,0 +1,135 @@ + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.java new file mode 100644 index 0000000000..3c8aacb86e --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesDialog.java @@ -0,0 +1,181 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.experimental.autoingest; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import javax.swing.JFrame; +import org.openide.windows.WindowManager; +import org.openide.util.NbBundle.Messages; + +/** + * This dialog shows the system administrator the orphaned znodes to be deleted. + * If 'OK' is selected, isOkSelected() will return true. + */ +class DeleteOrphanCaseNodesDialog extends javax.swing.JDialog { + private static final long serialVersionUID = 1L; + + private static final String NEW_LINE = System.getProperty("line.separator"); + + private boolean okSelected = false; + + /** + * Creates new form DeleteOrphanCaseNodesDialog + * + * @param zNodeCases The list of cases with nodes to be deleted + */ + DeleteOrphanCaseNodesDialog(Collection zNodeCases) { + super((JFrame) WindowManager.getDefault().getMainWindow(), null, true); + initComponents(); + additionalInit(zNodeCases); + } + + /** + * displays this dialog as child of main window. + */ + void display() { + this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); + setVisible(true); + } + + @Messages({ + "# {0} - item count", + "DeleteOrphanCaseNodesDialog.additionalInit.lblNodeCount.text=Znodes found: {0}", + "# {0} - item count", + "DeleteOrphanCaseNodesDialog.additionalInit.znodesTextArea.countMessage=ZNODES FOUND: {0}" + }) + private void additionalInit(Collection zNodeCases) { + List casesList = (zNodeCases == null) ? new ArrayList<>() : new ArrayList<>(zNodeCases); + int count = casesList.size(); + casesList.sort(Comparator.comparing(String::toString)); + String textAreaText = Bundle.DeleteOrphanCaseNodesDialog_additionalInit_znodesTextArea_countMessage(count) + + NEW_LINE + + NEW_LINE + + String.join(NEW_LINE, casesList); + + znodesTextArea.setText(textAreaText); + + lblNodeCount.setText(Bundle.DeleteOrphanCaseNodesDialog_additionalInit_lblNodeCount_text(count)); + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.JLabel descriptionText = new javax.swing.JLabel(); + javax.swing.JScrollPane jScrollPane = new javax.swing.JScrollPane(); + znodesTextArea = new javax.swing.JTextArea(); + javax.swing.JButton cancelButton = new javax.swing.JButton(); + javax.swing.JButton okButton = new javax.swing.JButton(); + lblNodeCount = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle(org.openide.util.NbBundle.getMessage(DeleteOrphanCaseNodesDialog.class, "DeleteOrphanCaseNodesDialog.titleText.text")); // NOI18N + setMinimumSize(new java.awt.Dimension(535, 226)); + + org.openide.awt.Mnemonics.setLocalizedText(descriptionText, org.openide.util.NbBundle.getMessage(DeleteOrphanCaseNodesDialog.class, "DeleteOrphanCaseNodesDialog.descriptionText.text")); // NOI18N + descriptionText.setVerticalAlignment(javax.swing.SwingConstants.TOP); + + znodesTextArea.setEditable(false); + znodesTextArea.setColumns(20); + znodesTextArea.setLineWrap(true); + znodesTextArea.setRows(5); + jScrollPane.setViewportView(znodesTextArea); + + org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(DeleteOrphanCaseNodesDialog.class, "DeleteOrphanCaseNodesDialog.cancelButton.text")); // NOI18N + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(DeleteOrphanCaseNodesDialog.class, "DeleteOrphanCaseNodesDialog.okButton.text")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(lblNodeCount, org.openide.util.NbBundle.getMessage(DeleteOrphanCaseNodesDialog.class, "DeleteOrphanCaseNodesDialog.lblNodeCount.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(descriptionText, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(lblNodeCount, javax.swing.GroupLayout.PREFERRED_SIZE, 310, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(okButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(descriptionText) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 252, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton) + .addComponent(okButton) + .addComponent(lblNodeCount)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + okSelected = true; + dispose(); + }//GEN-LAST:event_okButtonActionPerformed + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + dispose(); + }//GEN-LAST:event_cancelButtonActionPerformed + + /** + * If the system administrator selected OK. + * + * @return Whether or not 'OK' was selected by the system administrator. + */ + boolean isOkSelected() { + return okSelected; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel lblNodeCount; + private javax.swing.JTextArea znodesTextArea; + // End of variables declaration//GEN-END:variables +} diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesTask.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesTask.java index 16f0592548..63a3051d9b 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesTask.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/DeleteOrphanCaseNodesTask.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019-2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,10 +19,17 @@ package org.sleuthkit.autopsy.experimental.autoingest; import java.io.File; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Level; +import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils; import static org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils.isCaseAutoIngestLogNodePath; @@ -40,8 +47,8 @@ final class DeleteOrphanCaseNodesTask implements Runnable { private static final Logger logger = AutoIngestDashboardLogger.getLogger(); private final ProgressIndicator progress; - private int nodesCount; - private int casesCount; + private int nodesCount = 0; + private int casesCount = 0; /** * Constucts an instance of a task for deleting case coordination service @@ -53,6 +60,130 @@ final class DeleteOrphanCaseNodesTask implements Runnable { this.progress = progress; } + /** + * Retrieves an instance of the coordination service in order to fetch + * znodes and potentially delete. + * + * @return The coordination service or null on error. + */ + private CoordinationService getCoordinationService() { + progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc()); + logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc()); + CoordinationService coordinationService = null; + try { + coordinationService = CoordinationService.getInstance(); + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.SEVERE, "Error connecting to the coordination service", ex); //NON-NLS + } + return coordinationService; + } + + /** + * Retrieves node paths for cases. + * + * @param coordinationService The coordination service to use in order to + * fetch the node paths. + * + * @return The list of node paths for cases. + */ + private List getNodePaths(CoordinationService coordinationService) { + progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseZnodes()); + logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseZnodes()); + List nodePaths = null; + try { + nodePaths = coordinationService.getNodeList(CoordinationService.CategoryNode.CASES); + // in the event that getNodeList returns null (but still successful) return empty list + if (nodePaths == null) { + return new ArrayList(); + } + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.SEVERE, "Error getting case znode list", ex); //NON-NLS + } catch (InterruptedException unused) { + logger.log(Level.WARNING, "Task cancelled while getting case znode list"); //NON-NLS + } + + return nodePaths; + } + + private void addIfExists(List paths, String path) { + if (path != null && !path.isEmpty()) { + paths.add(path); + } + } + + /** + * Determines orphaned znode paths. + * + * @param nodePaths The list of case node paths. + * + * @return The list of orphaned node paths. + */ + private Map> getOrphanedNodes(List nodePaths) { + progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); + logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); + Map> nodePathsToDelete = new HashMap<>(); + for (String caseNodePath : nodePaths) { + if (isCaseNameNodePath(caseNodePath) || isCaseResourcesNodePath(caseNodePath) || isCaseAutoIngestLogNodePath(caseNodePath)) { + continue; + } + + final Path caseDirectoryPath = Paths.get(caseNodePath); + final File caseDirectory = caseDirectoryPath.toFile(); + if (!caseDirectory.exists()) { + String caseName = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath); + List paths = new ArrayList<>(); + + addIfExists(paths, CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath)); + addIfExists(paths, CoordinationServiceUtils.getCaseResourcesNodePath(caseDirectoryPath)); + addIfExists(paths, CoordinationServiceUtils.getCaseAutoIngestLogNodePath(caseDirectoryPath)); + addIfExists(paths, CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath)); + nodePathsToDelete.put(caseName, paths); + } + } + return nodePathsToDelete; + } + + /** + * Boxed boolean so that promptUser method can set a value on a final object + * from custom jdialog message. + */ + private class PromptResult { + + private boolean value = false; + + boolean isValue() { + return value; + } + + void setValue(boolean value) { + this.value = value; + } + + } + + /** + * prompts the user with a list of orphaned znodes. + * + * @param orphanedNodes The orphaned znode cases. + * + * @return True if the user would like to proceed deleting the znodes. + */ + private boolean promptUser(Collection orphanedNodes) { + final PromptResult dialogResult = new PromptResult(); + try { + SwingUtilities.invokeAndWait(() -> { + DeleteOrphanCaseNodesDialog dialog = new DeleteOrphanCaseNodesDialog(orphanedNodes); + dialog.display(); + dialogResult.setValue(dialog.isOkSelected()); + }); + + return dialogResult.isValue(); + } catch (InterruptedException | InvocationTargetException e) { + logger.log(Level.WARNING, "Task cancelled while confirming case znodes to delete"); //NON-NLS + return false; + } + } + @Override @NbBundle.Messages({ "DeleteOrphanCaseNodesTask.progress.startMessage=Starting orphaned case znode cleanup", @@ -63,67 +194,21 @@ final class DeleteOrphanCaseNodesTask implements Runnable { public void run() { progress.start(Bundle.DeleteOrphanCaseNodesTask_progress_startMessage()); try { - progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc()); - logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_connectingToCoordSvc()); - CoordinationService coordinationService; - try { - coordinationService = CoordinationService.getInstance(); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.SEVERE, "Error connecting to the coordination service", ex); //NON-NLS + CoordinationService coordinationService = getCoordinationService(); + if (coordinationService == null) { return; } - progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseZnodes()); - logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_gettingCaseZnodes()); - List nodePaths; - try { - nodePaths = coordinationService.getNodeList(CoordinationService.CategoryNode.CASES); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.SEVERE, "Error getting case znode list", ex); //NON-NLS - return; - } catch (InterruptedException unused) { - logger.log(Level.WARNING, "Task cancelled while getting case znode list"); //NON-NLS + List nodePaths = getNodePaths(coordinationService); + if (nodePaths == null) { return; } - progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); - logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); - for (String caseNodePath : nodePaths) { - if (isCaseNameNodePath(caseNodePath) || isCaseResourcesNodePath(caseNodePath) || isCaseAutoIngestLogNodePath(caseNodePath)) { - continue; - } + Map> orphanedNodes = getOrphanedNodes(nodePaths); + boolean continueDelete = promptUser(orphanedNodes.keySet()); - final Path caseDirectoryPath = Paths.get(caseNodePath); - final File caseDirectory = caseDirectoryPath.toFile(); - if (!caseDirectory.exists()) { - String caseName = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath); - String nodePath = ""; // NON-NLS - try { - nodePath = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); - - nodePath = CoordinationServiceUtils.getCaseResourcesNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); - - nodePath = CoordinationServiceUtils.getCaseAutoIngestLogNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); - - nodePath = CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); - - ++casesCount; - - /* - * Back to looking for orphans... - */ - progress.progress(Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); - logger.log(Level.INFO, Bundle.DeleteOrphanCaseNodesTask_progress_lookingForOrphanedCaseZnodes()); - - } catch (InterruptedException unused) { - logger.log(Level.WARNING, String.format("Task cancelled while deleting orphaned znode %s for %s", nodePath, caseName)); //NON-NLS - return; - } - } + if (continueDelete) { + deleteNodes(coordinationService, orphanedNodes); } } catch (Exception ex) { @@ -142,6 +227,32 @@ final class DeleteOrphanCaseNodesTask implements Runnable { } } + /** + * Deletes the orphaned znodes provided in the 'orphanedNodes' variable. + * + * @param coordinationService The coordination service to use for deletion. + * @param orphanedNodes A mapping of case to the orphaned znodes. + * + * @throws InterruptedException If the thread executing this task is + * interrupted during the delete operation. + */ + private void deleteNodes(CoordinationService coordinationService, Map> orphanedNodes) { + String caseName = null; + String nodePath = null; + try { + for (Entry> caseNodePaths : orphanedNodes.entrySet()) { + caseName = caseNodePaths.getKey(); + for (String path : caseNodePaths.getValue()) { + nodePath = path; + deleteNode(coordinationService, caseName, nodePath); + } + ++casesCount; + } + } catch (InterruptedException unused) { + logger.log(Level.WARNING, String.format("Task cancelled while deleting orphaned znode %s for %s", nodePath, caseName)); //NON-NLS + } + } + /** * Attempts to delete a case coordination service node. * diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form index 760f823543..7aa013e047 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.form @@ -25,7 +25,7 @@ - +
@@ -42,15 +42,15 @@ - + - - + + @@ -59,70 +59,68 @@ - - - - - + + + + + - - - - - - - - - - - - - + + + + + + - + + + + + - + + + - - - - - - - - - - - + + + - - - - + + + + + + + + + + + - + @@ -177,7 +175,7 @@ - + @@ -192,7 +190,7 @@ - + @@ -225,6 +223,15 @@ + + + + + + + + + @@ -235,6 +242,15 @@ + + + + + + + + + @@ -245,6 +261,15 @@ + + + + + + + + + @@ -332,13 +357,13 @@
- + - + - + @@ -373,6 +398,15 @@
+ + + + + + + + + @@ -383,6 +417,15 @@ + + + + + + + + + @@ -423,6 +466,15 @@ + + + + + + + + + @@ -478,19 +530,19 @@ - + - - + + - + - + diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.java index fcd21dd8f2..696c33ccb4 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/AutoIngestSettingsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2015-2018 Basis Technology Corp. + * Copyright 2015-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,6 @@ import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; -import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.FileUtil; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.coreutils.Logger; @@ -644,7 +643,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { nodeScrollPane.setMinimumSize(new java.awt.Dimension(0, 0)); - nodePanel.setMinimumSize(new java.awt.Dimension(100, 100)); + nodePanel.setMinimumSize(new java.awt.Dimension(0, 0)); tbOops.setEditable(false); tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, tbOops.getFont().getSize()+1)); @@ -654,6 +653,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(bnEditIngestSettings, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.bnEditIngestSettings.text")); // NOI18N bnEditIngestSettings.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.bnEditIngestSettings.toolTipText")); // NOI18N + bnEditIngestSettings.setMaximumSize(new java.awt.Dimension(200, 25)); + bnEditIngestSettings.setMinimumSize(new java.awt.Dimension(170, 25)); + bnEditIngestSettings.setPreferredSize(new java.awt.Dimension(170, 25)); bnEditIngestSettings.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnEditIngestSettingsActionPerformed(evt); @@ -661,6 +663,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { }); org.openide.awt.Mnemonics.setLocalizedText(bnAdvancedSettings, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.bnAdvancedSettings.text")); // NOI18N + bnAdvancedSettings.setMaximumSize(new java.awt.Dimension(200, 25)); + bnAdvancedSettings.setMinimumSize(new java.awt.Dimension(170, 25)); + bnAdvancedSettings.setPreferredSize(new java.awt.Dimension(170, 25)); bnAdvancedSettings.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnAdvancedSettingsActionPerformed(evt); @@ -668,6 +673,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { }); org.openide.awt.Mnemonics.setLocalizedText(bnFileExport, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.bnFileExport.text")); // NOI18N + bnFileExport.setMaximumSize(new java.awt.Dimension(200, 25)); + bnFileExport.setMinimumSize(new java.awt.Dimension(170, 25)); + bnFileExport.setPreferredSize(new java.awt.Dimension(170, 25)); bnFileExport.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnFileExportActionPerformed(evt); @@ -707,9 +715,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { jLabelSelectOutputFolder.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM); org.openide.awt.Mnemonics.setLocalizedText(sharedConfigCheckbox, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.sharedConfigCheckbox.text")); // NOI18N - sharedConfigCheckbox.setMaximumSize(new java.awt.Dimension(191, 14)); - sharedConfigCheckbox.setMinimumSize(new java.awt.Dimension(191, 14)); - sharedConfigCheckbox.setPreferredSize(new java.awt.Dimension(191, 14)); + sharedConfigCheckbox.setMaximumSize(new java.awt.Dimension(191, 21)); + sharedConfigCheckbox.setMinimumSize(new java.awt.Dimension(191, 21)); + sharedConfigCheckbox.setPreferredSize(new java.awt.Dimension(191, 21)); sharedConfigCheckbox.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { sharedConfigCheckboxItemStateChanged(evt); @@ -726,6 +734,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(browseSharedSettingsButton, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.browseSharedSettingsButton.text")); // NOI18N browseSharedSettingsButton.setEnabled(false); + browseSharedSettingsButton.setMaximumSize(new java.awt.Dimension(200, 25)); + browseSharedSettingsButton.setMinimumSize(new java.awt.Dimension(170, 25)); + browseSharedSettingsButton.setPreferredSize(new java.awt.Dimension(170, 25)); browseSharedSettingsButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { browseSharedSettingsButtonActionPerformed(evt); @@ -733,6 +744,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { }); org.openide.awt.Mnemonics.setLocalizedText(downloadButton, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.downloadButton.text")); // NOI18N + downloadButton.setMaximumSize(new java.awt.Dimension(200, 25)); + downloadButton.setMinimumSize(new java.awt.Dimension(170, 25)); + downloadButton.setPreferredSize(new java.awt.Dimension(170, 25)); downloadButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { downloadButtonActionPerformed(evt); @@ -749,6 +763,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jLabelCurrentTask, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.jLabelCurrentTask.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(uploadButton, org.openide.util.NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.uploadButton.text")); // NOI18N + uploadButton.setMaximumSize(new java.awt.Dimension(200, 25)); + uploadButton.setMinimumSize(new java.awt.Dimension(170, 25)); + uploadButton.setPreferredSize(new java.awt.Dimension(170, 25)); uploadButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { uploadButtonActionPerformed(evt); @@ -805,8 +822,8 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { .addGroup(pnTestMultiUserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lbTestResultText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(pnTestMultiUserLayout.createSequentialGroup() - .addComponent(lbTestMultiUserText) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 236, Short.MAX_VALUE) + .addComponent(lbTestMultiUserText, javax.swing.GroupLayout.DEFAULT_SIZE, 324, Short.MAX_VALUE) + .addGap(236, 236, 236) .addComponent(bnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(lbMultiUserResult, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -840,57 +857,63 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { .addComponent(jLabelInvalidImageFolder, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(nodePanelLayout.createSequentialGroup() .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pbTaskInProgress, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(nodePanelLayout.createSequentialGroup() - .addComponent(jLabelCurrentTask) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, nodePanelLayout.createSequentialGroup() + .addComponent(sharedConfigCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabelTaskDescription, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(sharedSettingsErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 445, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(30, 30, 30)) .addGroup(nodePanelLayout.createSequentialGroup() .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(nodePanelLayout.createSequentialGroup() - .addComponent(outputPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 630, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseOutputFolderButton)) + .addComponent(jLabelCurrentTask) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabelTaskDescription, javax.swing.GroupLayout.PREFERRED_SIZE, 626, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(nodePanelLayout.createSequentialGroup() .addComponent(inputPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 630, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(browseInputFolderButton)) - .addComponent(uploadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(masterNodeCheckBox) + .addComponent(uploadButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(nodePanelLayout.createSequentialGroup() - .addComponent(bnEditIngestSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnEditIngestSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnAdvancedSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnAdvancedSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnFileExport, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(bnFileExport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(nodePanelLayout.createSequentialGroup() .addComponent(jLabelSelectOutputFolder) .addGap(18, 18, 18) .addComponent(jLabelInvalidResultsFolder, javax.swing.GroupLayout.PREFERRED_SIZE, 544, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(nodePanelLayout.createSequentialGroup() - .addComponent(sharedConfigCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(sharedSettingsErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(nodePanelLayout.createSequentialGroup() .addComponent(sharedSettingsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseSharedSettingsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(nodePanelLayout.createSequentialGroup() - .addComponent(downloadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 143, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(configButtonErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 396, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(browseSharedSettingsButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(nodePanelLayout.createSequentialGroup() .addComponent(examinerModeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 561, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, 561, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(downloadButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(autoIngestModeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(0, 0, Short.MAX_VALUE))) .addGap(10, 10, 10)) .addGroup(nodePanelLayout.createSequentialGroup() - .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(autoIngestModeRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 145, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(pnTestMultiUser, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(configButtonErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 531, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(masterNodeCheckBox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, nodePanelLayout.createSequentialGroup() + .addComponent(outputPathTextField) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(browseOutputFolderButton)) + .addComponent(pbTaskInProgress, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); + + nodePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnAdvancedSettings, bnEditIngestSettings, bnFileExport, browseSharedSettingsButton, downloadButton, uploadButton}); + + nodePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {inputPathTextField, outputPathTextField}); + + nodePanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {browseInputFolderButton, browseOutputFolderButton}); + nodePanelLayout.setVerticalGroup( nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(nodePanelLayout.createSequentialGroup() @@ -918,9 +941,9 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { .addComponent(outputPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(25, 25, 25) .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnEditIngestSettings) - .addComponent(bnFileExport) - .addComponent(bnAdvancedSettings)) + .addComponent(bnEditIngestSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnFileExport, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnAdvancedSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(sharedConfigCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -928,15 +951,15 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(sharedSettingsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(browseSharedSettingsButton)) + .addComponent(browseSharedSettingsButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(downloadButton) - .addComponent(configButtonErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(downloadButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(configButtonErrorTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(masterNodeCheckBox, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(uploadButton) + .addComponent(uploadButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(8, 8, 8) .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabelCurrentTask) @@ -945,7 +968,7 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { .addComponent(pbTaskInProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(pnTestMultiUser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(82, Short.MAX_VALUE)) + .addContainerGap(20, Short.MAX_VALUE)) ); nodeScrollPane.setViewportView(nodePanel); @@ -958,193 +981,10 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 656, Short.MAX_VALUE) + .addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); }// //GEN-END:initComponents - boolean permissionsAppropriate(String path) { - return FileUtil.hasReadWriteAccess(Paths.get(path)); - } - - private void setSharedConfigEnable() { - setEnabledStateForSharedConfiguration(); - if (sharedConfigCheckbox.isEnabled() && sharedConfigCheckbox.isSelected()) { - sharedSettingsTextField.setEnabled(true); - browseSharedSettingsButton.setEnabled(true); - masterNodeCheckBox.setEnabled(true); - downloadButton.setEnabled(true); - validateSettings(); - controller.changed(); - } else { - sharedSettingsTextField.setEnabled(false); - browseSharedSettingsButton.setEnabled(false); - masterNodeCheckBox.setEnabled(false); - downloadButton.setEnabled(false); - sharedSettingsErrorTextField.setText(""); - validateSettings(); - controller.changed(); - } - } - - private void downloadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downloadButtonActionPerformed - // First save the shared config folder and solr settings to the properties - String globalSettingsPath = getNormalizedFolderPath(sharedSettingsTextField.getText().trim()); - AutoIngestUserPreferences.setSharedConfigFolder(globalSettingsPath); - - enableUI(false); - jLabelCurrentTask.setEnabled(true); - jLabelTaskDescription.setEnabled(true); - pbTaskInProgress.setEnabled(true); - pbTaskInProgress.setIndeterminate(true); - - UpdateConfigSwingWorker worker = new UpdateConfigSwingWorker(ConfigTaskType.DOWNLOAD); - try { - worker.execute(); - } catch (Exception ex) { - jLabelTaskDescription.setText(ex.getLocalizedMessage()); - } - }//GEN-LAST:event_downloadButtonActionPerformed - - private void uploadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uploadButtonActionPerformed - store(); - - enableUI(false); - jLabelCurrentTask.setEnabled(true); - jLabelTaskDescription.setEnabled(true); - pbTaskInProgress.setEnabled(true); - pbTaskInProgress.setIndeterminate(true); - - UpdateConfigSwingWorker worker = new UpdateConfigSwingWorker(ConfigTaskType.UPLOAD); - try { - worker.execute(); - } catch (Exception ex) { - jLabelTaskDescription.setText(ex.getLocalizedMessage()); - } - }//GEN-LAST:event_uploadButtonActionPerformed - - private void masterNodeCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_masterNodeCheckBoxItemStateChanged - // Enable the global settings text box and browse button iff the checkbox is checked and enabled - setEnabledStateForSharedConfiguration(); - if (masterNodeCheckBox.isEnabled() && masterNodeCheckBox.isSelected()) { - uploadButton.setEnabled(true); - validateSettings(); // This will disable the upload/save button if the settings aren't currently valid - controller.changed(); - } else { - uploadButton.setEnabled(false); - } - }//GEN-LAST:event_masterNodeCheckBoxItemStateChanged - - private void browseSharedSettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseSharedSettingsButtonActionPerformed - - String oldText = sharedSettingsTextField.getText().trim(); - // set the current directory of the FileChooser if the oldText is valid - File currentDir = new File(oldText); - if (currentDir.exists()) { - fc.setCurrentDirectory(currentDir); - } - - fc.setDialogTitle("Select shared configuration folder:"); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - int retval = fc.showOpenDialog(this); - if (retval == JFileChooser.APPROVE_OPTION) { - String path = fc.getSelectedFile().getPath(); - sharedSettingsTextField.setText(path); - validateSettings(); - controller.changed(); - } - }//GEN-LAST:event_browseSharedSettingsButtonActionPerformed - - private void sharedConfigCheckboxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_sharedConfigCheckboxItemStateChanged - // Enable the global settings text box and browse button iff the checkbox is checked and enabled - setSharedConfigEnable(); - }//GEN-LAST:event_sharedConfigCheckboxItemStateChanged - - private void browseOutputFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseOutputFolderButtonActionPerformed - String oldText = outputPathTextField.getText().trim(); - // set the current directory of the FileChooser if the oldText is valid - File currentDir = new File(oldText); - if (currentDir.exists()) { - fc.setCurrentDirectory(currentDir); - } - - fc.setDialogTitle("Select case output folder:"); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - int retval = fc.showOpenDialog(this); - if (retval == JFileChooser.APPROVE_OPTION) { - String path = fc.getSelectedFile().getPath(); - outputPathTextField.setText(path); - validateSettings(); - controller.changed(); - } - }//GEN-LAST:event_browseOutputFolderButtonActionPerformed - - private void browseInputFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseInputFolderButtonActionPerformed - String oldText = inputPathTextField.getText().trim(); - // set the current directory of the FileChooser if the oldText is valid - File currentDir = new File(oldText); - if (currentDir.exists()) { - fc.setCurrentDirectory(currentDir); - } - - fc.setDialogTitle("Select case input folder:"); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - - int retval = fc.showOpenDialog(this); - if (retval == JFileChooser.APPROVE_OPTION) { - String path = fc.getSelectedFile().getPath(); - inputPathTextField.setText(path); - validateSettings(); - controller.changed(); - } - }//GEN-LAST:event_browseInputFolderButtonActionPerformed - - private void bnFileExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnFileExportActionPerformed - JDialog jDialog = new JDialog(); - FileExporterSettingsPanel fileExporterSettingsPanel = new FileExporterSettingsPanel(jDialog); - jDialog.addWindowListener(new java.awt.event.WindowAdapter() { - @Override - public void windowClosing(java.awt.event.WindowEvent windowEvent) { - fileExporterSettingsPanel.store(); - } - }); - JScrollPane jScrollPane = new JScrollPane(fileExporterSettingsPanel); - jScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - jScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - jScrollPane.setMinimumSize(new Dimension(100, 100)); - jDialog.add(jScrollPane); - jDialog.setTitle(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.FileExportRules.text")); - jDialog.setIconImage(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/frame32.gif")); - jDialog.setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL); - jDialog.pack(); - jDialog.setLocationRelativeTo(this); - jDialog.setVisible(true); - }//GEN-LAST:event_bnFileExportActionPerformed - - private void bnAdvancedSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnAdvancedSettingsActionPerformed - AdvancedAutoIngestSettingsPanel advancedAutoIngestSettingsPanel = new AdvancedAutoIngestSettingsPanel(getModeFromRadioButtons()); - if (JOptionPane.showConfirmDialog(this, advancedAutoIngestSettingsPanel, - NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.AdvancedAutoIngestSettingsPanel.Title"), - JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) { - advancedAutoIngestSettingsPanel.store(); - } - }//GEN-LAST:event_bnAdvancedSettingsActionPerformed - - private void bnEditIngestSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnEditIngestSettingsActionPerformed - displayIngestJobSettingsPanel(); - }//GEN-LAST:event_bnEditIngestSettingsActionPerformed - - private void autoIngestModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoIngestModeRadioButtonActionPerformed - enableOptionsBasedOnMode(getModeFromRadioButtons()); - controller.changed(); - }//GEN-LAST:event_autoIngestModeRadioButtonActionPerformed - - private void examinerModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_examinerModeRadioButtonActionPerformed - enableOptionsBasedOnMode(getModeFromRadioButtons()); - controller.changed(); - }//GEN-LAST:event_examinerModeRadioButtonActionPerformed - private void bnTestMultiUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestMultiUserActionPerformed lbTestResultText.setForeground(Color.BLACK); @@ -1176,6 +1016,189 @@ public class AutoIngestSettingsPanel extends javax.swing.JPanel { } }//GEN-LAST:event_bnTestMultiUserActionPerformed + private void autoIngestModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoIngestModeRadioButtonActionPerformed + enableOptionsBasedOnMode(getModeFromRadioButtons()); + controller.changed(); + }//GEN-LAST:event_autoIngestModeRadioButtonActionPerformed + + private void examinerModeRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_examinerModeRadioButtonActionPerformed + enableOptionsBasedOnMode(getModeFromRadioButtons()); + controller.changed(); + }//GEN-LAST:event_examinerModeRadioButtonActionPerformed + + private void masterNodeCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_masterNodeCheckBoxItemStateChanged + // Enable the global settings text box and browse button iff the checkbox is checked and enabled + setEnabledStateForSharedConfiguration(); + if (masterNodeCheckBox.isEnabled() && masterNodeCheckBox.isSelected()) { + uploadButton.setEnabled(true); + validateSettings(); // This will disable the upload/save button if the settings aren't currently valid + controller.changed(); + } else { + uploadButton.setEnabled(false); + } + }//GEN-LAST:event_masterNodeCheckBoxItemStateChanged + + private void uploadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uploadButtonActionPerformed + store(); + + enableUI(false); + jLabelCurrentTask.setEnabled(true); + jLabelTaskDescription.setEnabled(true); + pbTaskInProgress.setEnabled(true); + pbTaskInProgress.setIndeterminate(true); + + UpdateConfigSwingWorker worker = new UpdateConfigSwingWorker(ConfigTaskType.UPLOAD); + try { + worker.execute(); + } catch (Exception ex) { + jLabelTaskDescription.setText(ex.getLocalizedMessage()); + } + }//GEN-LAST:event_uploadButtonActionPerformed + + private void downloadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downloadButtonActionPerformed + // First save the shared config folder and solr settings to the properties + String globalSettingsPath = getNormalizedFolderPath(sharedSettingsTextField.getText().trim()); + AutoIngestUserPreferences.setSharedConfigFolder(globalSettingsPath); + + enableUI(false); + jLabelCurrentTask.setEnabled(true); + jLabelTaskDescription.setEnabled(true); + pbTaskInProgress.setEnabled(true); + pbTaskInProgress.setIndeterminate(true); + + UpdateConfigSwingWorker worker = new UpdateConfigSwingWorker(ConfigTaskType.DOWNLOAD); + try { + worker.execute(); + } catch (Exception ex) { + jLabelTaskDescription.setText(ex.getLocalizedMessage()); + } + }//GEN-LAST:event_downloadButtonActionPerformed + + private void browseSharedSettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseSharedSettingsButtonActionPerformed + + String oldText = sharedSettingsTextField.getText().trim(); + // set the current directory of the FileChooser if the oldText is valid + File currentDir = new File(oldText); + if (currentDir.exists()) { + fc.setCurrentDirectory(currentDir); + } + + fc.setDialogTitle("Select shared configuration folder:"); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int retval = fc.showOpenDialog(this); + if (retval == JFileChooser.APPROVE_OPTION) { + String path = fc.getSelectedFile().getPath(); + sharedSettingsTextField.setText(path); + validateSettings(); + controller.changed(); + } + }//GEN-LAST:event_browseSharedSettingsButtonActionPerformed + + private void sharedConfigCheckboxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_sharedConfigCheckboxItemStateChanged + // Enable the global settings text box and browse button iff the checkbox is checked and enabled + setSharedConfigEnable(); + }//GEN-LAST:event_sharedConfigCheckboxItemStateChanged + + private void browseInputFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseInputFolderButtonActionPerformed + String oldText = inputPathTextField.getText().trim(); + // set the current directory of the FileChooser if the oldText is valid + File currentDir = new File(oldText); + if (currentDir.exists()) { + fc.setCurrentDirectory(currentDir); + } + + fc.setDialogTitle("Select case input folder:"); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int retval = fc.showOpenDialog(this); + if (retval == JFileChooser.APPROVE_OPTION) { + String path = fc.getSelectedFile().getPath(); + inputPathTextField.setText(path); + validateSettings(); + controller.changed(); + } + }//GEN-LAST:event_browseInputFolderButtonActionPerformed + + private void browseOutputFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseOutputFolderButtonActionPerformed + String oldText = outputPathTextField.getText().trim(); + // set the current directory of the FileChooser if the oldText is valid + File currentDir = new File(oldText); + if (currentDir.exists()) { + fc.setCurrentDirectory(currentDir); + } + + fc.setDialogTitle("Select case output folder:"); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int retval = fc.showOpenDialog(this); + if (retval == JFileChooser.APPROVE_OPTION) { + String path = fc.getSelectedFile().getPath(); + outputPathTextField.setText(path); + validateSettings(); + controller.changed(); + } + }//GEN-LAST:event_browseOutputFolderButtonActionPerformed + + private void bnFileExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnFileExportActionPerformed + JDialog jDialog = new JDialog(); + FileExporterSettingsPanel fileExporterSettingsPanel = new FileExporterSettingsPanel(jDialog); + jDialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent windowEvent) { + fileExporterSettingsPanel.store(); + } + }); + JScrollPane jScrollPane = new JScrollPane(fileExporterSettingsPanel); + jScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + jScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + jScrollPane.setMinimumSize(new Dimension(100, 100)); + jDialog.add(jScrollPane); + jDialog.setTitle(NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.FileExportRules.text")); + jDialog.setIconImage(ImageUtilities.loadImage("org/sleuthkit/autopsy/experimental/images/frame32.gif")); + jDialog.setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL); + jDialog.pack(); + jDialog.setLocationRelativeTo(this); + jDialog.setVisible(true); + }//GEN-LAST:event_bnFileExportActionPerformed + + private void bnAdvancedSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnAdvancedSettingsActionPerformed + AdvancedAutoIngestSettingsPanel advancedAutoIngestSettingsPanel = new AdvancedAutoIngestSettingsPanel(getModeFromRadioButtons()); + if (JOptionPane.showConfirmDialog(this, advancedAutoIngestSettingsPanel, + NbBundle.getMessage(AutoIngestSettingsPanel.class, "AutoIngestSettingsPanel.AdvancedAutoIngestSettingsPanel.Title"), + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) { + advancedAutoIngestSettingsPanel.store(); + } + }//GEN-LAST:event_bnAdvancedSettingsActionPerformed + + private void bnEditIngestSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnEditIngestSettingsActionPerformed + displayIngestJobSettingsPanel(); + }//GEN-LAST:event_bnEditIngestSettingsActionPerformed + + boolean permissionsAppropriate(String path) { + return FileUtil.hasReadWriteAccess(Paths.get(path)); + } + + private void setSharedConfigEnable() { + setEnabledStateForSharedConfiguration(); + if (sharedConfigCheckbox.isEnabled() && sharedConfigCheckbox.isSelected()) { + sharedSettingsTextField.setEnabled(true); + browseSharedSettingsButton.setEnabled(true); + masterNodeCheckBox.setEnabled(true); + downloadButton.setEnabled(true); + validateSettings(); + controller.changed(); + } else { + sharedSettingsTextField.setEnabled(false); + browseSharedSettingsButton.setEnabled(false); + masterNodeCheckBox.setEnabled(false); + downloadButton.setEnabled(false); + sharedSettingsErrorTextField.setText(""); + validateSettings(); + controller.changed(); + } + } + private void enableUI(boolean state) { enableOptionsBasedOnMode(OptionsUiMode.DOWNLOADING_CONFIGURATION); downloadButton.setEnabled(state); diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index 3d202a963b..0e4face2bc 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -44,7 +44,6 @@ from org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints import Tr from org.sleuthkit.autopsy.datamodel import ContentUtils from org.sleuthkit.autopsy.ingest import IngestModule from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException -from org.sleuthkit.autopsy.ingest import DataSourceIngestModule from org.sleuthkit.autopsy.ingest import FileIngestModule from org.sleuthkit.autopsy.ingest import IngestModuleFactoryAdapter from org.sleuthkit.autopsy.ingest import IngestMessage @@ -60,12 +59,17 @@ import gpxpy import gpxpy.gpx import gpxpy.parser +# to get a random filename to prevent race conditions +import uuid + # Factory that defines the name and details of the module and allows Autopsy # to create instances of the modules that will do the analysis. -class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): + + +class GPXParserFileIngestModuleFactory(IngestModuleFactoryAdapter): moduleName = "GPX Parser" - + def getModuleDisplayName(self): return self.moduleName @@ -75,158 +79,176 @@ class GPXParserDataSourceIngestModuleFactory(IngestModuleFactoryAdapter): def getModuleVersionNumber(self): return "1.2" - def isDataSourceIngestModuleFactory(self): + def isFileIngestModuleFactory(self): return True - def createDataSourceIngestModule(self, ingestOptions): - return GPXParserDataSourceIngestModule() + def createFileIngestModule(self, ingestOptions): + return GPXParserFileIngestModule() - -# Data Source-level ingest module. One gets created per data source. -class GPXParserDataSourceIngestModule(DataSourceIngestModule): - logger = Logger.getLogger(GPXParserDataSourceIngestModuleFactory.moduleName) +# File level ingest module. +class GPXParserFileIngestModule(FileIngestModule): + + logger = Logger.getLogger( + GPXParserFileIngestModuleFactory.moduleName) writeDebugMsgs = False def log(self, level, msg): - self.logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) + self.logger.logp(level, self.__class__.__name__, + inspect.stack()[1][3], msg) def __init__(self): self.context = None - - # Where any setup and configuration is done. - def startUp(self, context): - self.context = context - - # Where the analysis is done. - def process(self, dataSource, progressBar): - - # We don't know how much work there is yet. - progressBar.switchToIndeterminate() - - # Get the case database and its blackboard. - skCase = Case.getCurrentCase().getSleuthkitCase() - blackboard = skCase.getBlackboard() - - # Get any files with a .gpx extension. - # It would perhaps be better to get these files by MIME type instead. - # RC: It would also be better if this were a file level ingest module so it could process files extracted from archives. - fileManager = Case.getCurrentCase().getServices().getFileManager() - files = fileManager.findFiles(dataSource, "%.gpx") - - # Update the progress bar now that we know how much work there is to do. - numFiles = len(files) - if self.writeDebugMsgs: self.log(Level.INFO, "Found " + str(numFiles) + " GPX files") - progressBar.switchToDeterminate(numFiles) + self.fileCount = 0 # Get the module name, it will be needed for adding attributes - moduleName = GPXParserDataSourceIngestModuleFactory.moduleName + self.moduleName = GPXParserFileIngestModuleFactory.moduleName - # Check if a folder for this module is present in the case Temp directory. + # Get the case database and its blackboard. + self.skCase = Case.getCurrentCase().getSleuthkitCase() + self.blackboard = self.skCase.getBlackboard() + + # Check if a folder for this module is present in the case Temp directory. # If not, create it. - dirName = os.path.join(Case.getCurrentCase().getTempDirectory(), "GPX_Parser_Module") + self.dirName = os.path.join( + Case.getCurrentCase().getTempDirectory(), "GPX_Parser_Module") try: - os.stat(dirName) + os.stat(self.dirName) except: - os.mkdir(dirName) + os.mkdir(self.dirName) - # Create a temp file name. It appears that we cannot close and delete + # Where any setup and configuration is done. + + def startUp(self, context): + self.context = context + self.fileCount = 0 + + # Where the file analysis is done. + def process(self, file): + if not file.getName().lower().endswith(".gpx"): + return IngestModule.ProcessResult.OK + + # Create a temp file name. It appears that we cannot close and delete # this file, but we can overwrite it for each file we need to process. - fileName = os.path.join(dirName, "tmp.gpx") - - fileCount = 0; - for file in files: + fileName = os.path.join(self.dirName, uuid.uuid4().hex + ".gpx") - # Create a GeoArtifactsHelper for this file. - geoArtifactHelper = GeoArtifactsHelper(skCase, moduleName, None, file) - - # Check if the user pressed cancel while we were busy. - if self.context.isJobCancelled(): - return IngestModule.ProcessResult.OK + # Create a GeoArtifactsHelper for this file. + geoArtifactHelper = GeoArtifactsHelper( + self.skCase, self.moduleName, None, file) - if self.writeDebugMsgs: self.log(Level.INFO, "Processing " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - fileCount += 1 + if self.writeDebugMsgs: + self.log(Level.INFO, "Processing " + file.getUniquePath() + + " (objID = " + str(file.getId()) + ")") - # Write the file so that it can be parsed by gpxpy. - localFile = File(fileName) - ContentUtils.writeToFile(file, localFile) + # Write the file so that it can be parsed by gpxpy. + localFile = File(fileName) + ContentUtils.writeToFile(file, localFile) - # Send the file to gpxpy for parsing. - gpxfile = open(fileName) - try: - gpx = gpxpy.parse(gpxfile) - if self.writeDebugMsgs: self.log(Level.INFO, "Parsed " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - except Exception as e: - self.log(Level.WARNING, "Error parsing file " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) - continue - - if gpx: - if self.writeDebugMsgs: self.log(Level.INFO, "Processing tracks from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - for track in gpx.tracks: - for segment in track.segments: - geoPointList = GeoTrackPoints() - for point in segment.points: + # Send the file to gpxpy for parsing. + gpxfile = open(fileName) + try: + gpx = gpxpy.parse(gpxfile) + if self.writeDebugMsgs: + self.log(Level.INFO, "Parsed " + file.getUniquePath() + + " (objID = " + str(file.getId()) + ")") + except Exception as e: + self.log(Level.WARNING, "Error parsing file " + file.getUniquePath() + + " (objID = " + str(file.getId()) + "):" + str(e)) + return IngestModule.ProcessResult.ERROR - elevation = 0 - if point.elevation != None: - elevation = point.elevation - - timeStamp = 0 - try: - if (point.time != None): - timeStamp = long(time.mktime(point.time.timetuple())) - except Exception as e: - self.log(Level.WARNING, "Error getting track timestamp from " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) + if gpx: + if self.writeDebugMsgs: + self.log(Level.INFO, "Processing tracks from " + + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - geoPointList.addPoint(TrackPoint(point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) - + for track in gpx.tracks: + for segment in track.segments: + geoPointList = GeoTrackPoints() + for point in segment.points: + + elevation = 0 + if point.elevation != None: + elevation = point.elevation + + timeStamp = 0 try: - geoArtifactHelper.addTrack("Track", geoPointList, None) - except Blackboard.BlackboardException as e: - self.log(Level.SEVERE, "Error posting GPS track artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - except TskCoreException as e: - self.log(Level.SEVERE, "Error creating GPS track artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - - if self.writeDebugMsgs: self.log(Level.INFO, "Processing waypoints from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - for waypoint in gpx.waypoints: - + if (point.time != None): + timeStamp = long(time.mktime( + point.time.timetuple())) + except Exception as e: + self.log(Level.WARNING, "Error getting track timestamp from " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + str(e)) + + geoPointList.addPoint(TrackPoint( + point.latitude, point.longitude, elevation, None, 0, 0, 0, timeStamp)) + try: - art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) - - attributes = ArrayList() - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), moduleName, waypoint.latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), moduleName, waypoint.longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FLAG.getTypeID(), moduleName, "Waypoint")) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), moduleName, waypoint.name)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), moduleName, "GPXParser")) - art.addAttributes(attributes) - - blackboard.postArtifact(art, moduleName) - + geoArtifactHelper.addTrack("Track", geoPointList, None) except Blackboard.BlackboardException as e: - self.log(Level.SEVERE, "Error posting GPS bookmark artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + self.log(Level.SEVERE, "Error posting GPS track artifact for " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) except TskCoreException as e: - self.log(Level.SEVERE, "Error creating GPS bookmark artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + self.log(Level.SEVERE, "Error creating GPS track artifact for " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - if self.writeDebugMsgs: self.log(Level.INFO, "Processing routes from " + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - for route in gpx.routes: + if self.writeDebugMsgs: + self.log(Level.INFO, "Processing waypoints from " + + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") - geoWaypoints = GeoWaypoints() + for waypoint in gpx.waypoints: - for point in route.points: - geoWaypoints.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) - - try: - geoArtifactHelper.addRoute(None, None, geoWaypoints, None) - except Blackboard.BlackboardException as e: - self.log("Error posting GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - except TskCoreException as e: - self.log(Level.SEVERE, "Error creating GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) - - # Update the progress bar. - progressBar.progress(fileCount) + try: + art = file.newArtifact( + BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) - # Post a message to the ingest messages inbox. - message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, moduleName, "Processed %d files" % fileCount) - IngestServices.getInstance().postMessage(message) - return IngestModule.ProcessResult.OK; + attributes = ArrayList() + attributes.add(BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), self.moduleName, waypoint.latitude)) + attributes.add(BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), self.moduleName, waypoint.longitude)) + attributes.add(BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_FLAG.getTypeID(), self.moduleName, "Waypoint")) + attributes.add(BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), self.moduleName, waypoint.name)) + attributes.add(BlackboardAttribute( + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), self.moduleName, "GPXParser")) + art.addAttributes(attributes) + + self.blackboard.postArtifact(art, self.moduleName) + + except Blackboard.BlackboardException as e: + self.log(Level.SEVERE, "Error posting GPS bookmark artifact for " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + except TskCoreException as e: + self.log(Level.SEVERE, "Error creating GPS bookmark artifact for " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + + if self.writeDebugMsgs: + self.log(Level.INFO, "Processing routes from " + + file.getUniquePath() + " (objID = " + str(file.getId()) + ")") + + for route in gpx.routes: + + geoWaypoints = GeoWaypoints() + + for point in route.points: + geoWaypoints.addPoint( + Waypoint(point.latitude, point.longitude, point.elevation, point.name)) + + try: + geoArtifactHelper.addRoute(None, None, geoWaypoints, None) + except Blackboard.BlackboardException as e: + self.log("Error posting GPS route artifact for " + file.getUniquePath() + + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + except TskCoreException as e: + self.log(Level.SEVERE, "Error creating GPS route artifact for " + + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) + + self.fileCount += 1 + return IngestModule.ProcessResult.OK + + def shutDown(self): + message = IngestMessage.createMessage( + IngestMessage.MessageType.DATA, GPXParserFileIngestModuleFactory.moduleName, + str(self.fileCount) + " files found") + ingestServices = IngestServices.getInstance().postMessage(message) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 3dd312becc..19f5a71cb7 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -301,21 +301,21 @@ DropdownListSearchPanel.jSaveSearchResults.text=Save search results GlobalEditListPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. -ExtractedContentPanel.hitCountLabel.text=- +ExtractedContentPanel.AccessibleContext.accessibleName= +ExtractedContentPanel.jLabel1.text=Text Source: +ExtractedContentPanel.hitNextButton.text= ExtractedContentPanel.hitPreviousButton.text= +ExtractedContentPanel.hitButtonsLabel.text=Match ExtractedContentPanel.hitTotalLabel.text=- ExtractedContentPanel.hitOfLabel.text=of -ExtractedContentPanel.hitNextButton.text= -ExtractedContentPanel.hitButtonsLabel.text=Match +ExtractedContentPanel.hitCountLabel.text=- ExtractedContentPanel.hitLabel.toolTipText= ExtractedContentPanel.hitLabel.text=Matches on page: -ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pageNextButton.text= ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton ExtractedContentPanel.pagePreviousButton.text= -ExtractedContentPanel.pageNextButton.text= -ExtractedContentPanel.pagesLabel.text=Page: -ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageButtonsLabel.text=Page +ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageOfLabel.text=of -ExtractedContentPanel.jLabel1.text=Text Source: -ExtractedContentPanel.AccessibleContext.accessibleName= +ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pagesLabel.text=Page: diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties index c131f5c8cf..b1d833f795 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties @@ -357,20 +357,20 @@ DropdownListSearchPanel.jSaveSearchResults.text=\u691c\u7d22\u7d50\u679c\u3092\u GlobalEditListPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 -ExtractedContentPanel.hitCountLabel.text=- +ExtractedContentPanel.jLabel1.text=\u30c6\u30ad\u30b9\u30c8\u30bd\u30fc\u30b9: +ExtractedContentPanel.hitNextButton.text= ExtractedContentPanel.hitPreviousButton.text= +ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c ExtractedContentPanel.hitTotalLabel.text=- ExtractedContentPanel.hitOfLabel.text=/ -ExtractedContentPanel.hitNextButton.text= -ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c +ExtractedContentPanel.hitCountLabel.text=- ExtractedContentPanel.hitLabel.toolTipText= ExtractedContentPanel.hitLabel.text=\u30da\u30fc\u30b8\u4e0a\u306e\u4e00\u81f4\u3059\u308b\u7d50\u679c: -ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pageNextButton.text= ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton ExtractedContentPanel.pagePreviousButton.text= -ExtractedContentPanel.pageNextButton.text= -ExtractedContentPanel.pagesLabel.text=\u30da\u30fc\u30b8: -ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageButtonsLabel.text=\u30da\u30fc\u30b8 +ExtractedContentPanel.pageTotalLabel.text=- ExtractedContentPanel.pageOfLabel.text=/ -ExtractedContentPanel.jLabel1.text=\u30c6\u30ad\u30b9\u30c8\u30bd\u30fc\u30b9: +ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pagesLabel.text=\u30da\u30fc\u30b8: diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index 2ed8bb9073..13e535f4ed 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -27,10 +27,10 @@ - + - + @@ -43,180 +43,87 @@ + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - + + + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + - - + + + + + + - + - + - + - - + + + - + + - + + + + + + + + + + + + + + + + + + + @@ -224,12 +131,23 @@ - + - - + + + + + + + + + + + + + @@ -239,10 +157,72 @@ - + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -272,16 +252,135 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + @@ -296,30 +395,11 @@ - - - - - - - + + - - - - - - - - - - - - - - - - + + @@ -352,96 +432,54 @@ - + - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - + + + - + - + + + + + + + + + + + + + + + + + @@ -451,11 +489,137 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 6cc5e01d42..8ff9c0fdcc 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -24,6 +24,7 @@ import java.awt.Font; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -46,6 +47,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.TextUtil; +import org.sleuthkit.autopsy.guiutils.WrapLayout; /** * Panel displays HTML content sent to ExtractedContentViewer, and provides a @@ -69,6 +71,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP ExtractedContentPanel() { initComponents(); + additionalInit(); setSources("", new ArrayList<>()); hitPreviousButton.setEnabled(false); hitNextButton.setEnabled(false); @@ -183,7 +186,12 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP } - + private void additionalInit() { + // use wrap layout for better component wrapping + WrapLayout layout = new WrapLayout(0,5); + layout.setOppositeAligned(Arrays.asList(textSourcePanel)); + controlPanel.setLayout(layout); + } /** @@ -198,29 +206,43 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP rightClickMenu = new javax.swing.JPopupMenu(); copyMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem(); - extractedScrollPane = new javax.swing.JScrollPane(); - extractedTextPane = new javax.swing.JTextPane(); - controlScrollPane = new javax.swing.JScrollPane(); controlPanel = new javax.swing.JPanel(); - sourceComboBox = new javax.swing.JComboBox<>(); - jLabel1 = new javax.swing.JLabel(); - pageOfLabel = new javax.swing.JLabel(); - pageButtonsLabel = new javax.swing.JLabel(); - pageTotalLabel = new javax.swing.JLabel(); + javax.swing.JPanel pagePanel = new javax.swing.JPanel(); pagesLabel = new javax.swing.JLabel(); - pageNextButton = new javax.swing.JButton(); - pagePreviousButton = new javax.swing.JButton(); + javax.swing.Box.Filler fillerSmall1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); pageCurLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerSmall2 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + pageOfLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerSmall3 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + pageTotalLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerSmall4 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + pageButtonsLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerMed1 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767)); + pagePreviousButton = new javax.swing.JButton(); + pageNextButton = new javax.swing.JButton(); + javax.swing.Box.Filler fillerSmall6 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + jSeparator2 = new javax.swing.JSeparator(); + javax.swing.JPanel matchesPanel = new javax.swing.JPanel(); hitLabel = new javax.swing.JLabel(); - hitButtonsLabel = new javax.swing.JLabel(); - hitNextButton = new javax.swing.JButton(); + hitCountLabel = new javax.swing.JLabel(); hitOfLabel = new javax.swing.JLabel(); hitTotalLabel = new javax.swing.JLabel(); + hitButtonsLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerMed2 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767)); hitPreviousButton = new javax.swing.JButton(); - hitCountLabel = new javax.swing.JLabel(); - jSeparator2 = new javax.swing.JSeparator(); + hitNextButton = new javax.swing.JButton(); + javax.swing.Box.Filler fillerSmall11 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); jSeparator3 = new javax.swing.JSeparator(); + javax.swing.JPanel zoomPanelWrapper = new javax.swing.JPanel(); zoomPanel = new TextZoomPanel(this); + javax.swing.Box.Filler fillerSmall14 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + jSeparator4 = new javax.swing.JSeparator(); + textSourcePanel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + javax.swing.Box.Filler fillerSmall12 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767)); + sourceComboBox = new javax.swing.JComboBox<>(); + extractedScrollPane = new javax.swing.JScrollPane(); + extractedTextPane = new javax.swing.JTextPane(); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N rightClickMenu.add(copyMenuItem); @@ -228,8 +250,156 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N rightClickMenu.add(selectAllMenuItem); - setMinimumSize(new java.awt.Dimension(100, 0)); - setPreferredSize(new java.awt.Dimension(100, 58)); + setMinimumSize(new java.awt.Dimension(250, 0)); + setPreferredSize(new java.awt.Dimension(250, 58)); + setLayout(new java.awt.BorderLayout()); + + controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); + + pagePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); + + pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagesLabel.text")); // NOI18N + pagePanel.add(pagesLabel); + pagePanel.add(fillerSmall1); + + pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N + pagePanel.add(pageCurLabel); + pagePanel.add(fillerSmall2); + + pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageOfLabel.text")); // NOI18N + pagePanel.add(pageOfLabel); + pagePanel.add(fillerSmall3); + + pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageTotalLabel.text")); // NOI18N + pagePanel.add(pageTotalLabel); + pagePanel.add(fillerSmall4); + + pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N + pagePanel.add(pageButtonsLabel); + pagePanel.add(fillerMed1); + + pagePreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N + pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.text")); // NOI18N + pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N + pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + pagePreviousButton.setBorderPainted(false); + pagePreviousButton.setContentAreaFilled(false); + pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N + pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + pagePanel.add(pagePreviousButton); + + pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N + pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageNextButton.text")); // NOI18N + pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + pageNextButton.setBorderPainted(false); + pageNextButton.setContentAreaFilled(false); + pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N + pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23)); + pagePanel.add(pageNextButton); + pagePanel.add(fillerSmall6); + + jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); + jSeparator2.setMaximumSize(new java.awt.Dimension(2, 25)); + jSeparator2.setMinimumSize(new java.awt.Dimension(2, 25)); + jSeparator2.setPreferredSize(new java.awt.Dimension(2, 25)); + pagePanel.add(jSeparator2); + + controlPanel.add(pagePanel); + + matchesPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); + + hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N + hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N + matchesPanel.add(hitLabel); + + hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitCountLabel.text")); // NOI18N + hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14)); + hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14)); + hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14)); + matchesPanel.add(hitCountLabel); + + hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitOfLabel.text")); // NOI18N + matchesPanel.add(hitOfLabel); + + hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitTotalLabel.text")); // NOI18N + hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14)); + hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14)); + hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14)); + matchesPanel.add(hitTotalLabel); + + hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N + matchesPanel.add(hitButtonsLabel); + matchesPanel.add(fillerMed2); + + hitPreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N + hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitPreviousButton.text")); // NOI18N + hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + hitPreviousButton.setBorderPainted(false); + hitPreviousButton.setContentAreaFilled(false); + hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N + hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23)); + hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N + matchesPanel.add(hitPreviousButton); + + hitNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N + hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitNextButton.text")); // NOI18N + hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + hitNextButton.setBorderPainted(false); + hitNextButton.setContentAreaFilled(false); + hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N + hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23)); + hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N + matchesPanel.add(hitNextButton); + matchesPanel.add(fillerSmall11); + + jSeparator3.setOrientation(javax.swing.SwingConstants.VERTICAL); + jSeparator3.setMaximumSize(new java.awt.Dimension(2, 25)); + jSeparator3.setMinimumSize(new java.awt.Dimension(2, 25)); + jSeparator3.setName(""); // NOI18N + jSeparator3.setPreferredSize(new java.awt.Dimension(2, 25)); + matchesPanel.add(jSeparator3); + + controlPanel.add(matchesPanel); + + zoomPanelWrapper.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); + + zoomPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); + zoomPanelWrapper.add(zoomPanel); + zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N + + zoomPanelWrapper.add(fillerSmall14); + + jSeparator4.setOrientation(javax.swing.SwingConstants.VERTICAL); + jSeparator4.setMaximumSize(new java.awt.Dimension(2, 25)); + jSeparator4.setMinimumSize(new java.awt.Dimension(2, 25)); + jSeparator4.setName(""); // NOI18N + jSeparator4.setPreferredSize(new java.awt.Dimension(2, 25)); + zoomPanelWrapper.add(jSeparator4); + + controlPanel.add(zoomPanelWrapper); + + textSourcePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0)); + + jLabel1.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.jLabel1.text")); // NOI18N + textSourcePanel.add(jLabel1); + textSourcePanel.add(fillerSmall12); + + sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel()); + sourceComboBox.setMaximumSize(new java.awt.Dimension(150, 32767)); + sourceComboBox.setMinimumSize(new java.awt.Dimension(150, 25)); + sourceComboBox.setPreferredSize(new java.awt.Dimension(150, 25)); + textSourcePanel.add(sourceComboBox); + + controlPanel.add(textSourcePanel); + + add(controlPanel, java.awt.BorderLayout.NORTH); extractedScrollPane.setBackground(new java.awt.Color(255, 255, 255)); extractedScrollPane.setPreferredSize(new java.awt.Dimension(640, 29)); @@ -241,192 +411,10 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP extractedTextPane.setPreferredSize(new java.awt.Dimension(600, 29)); extractedScrollPane.setViewportView(extractedTextPane); - controlScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - controlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); - controlScrollPane.setPreferredSize(new java.awt.Dimension(600, 100)); - - controlPanel.setMinimumSize(new java.awt.Dimension(0, 20)); - controlPanel.setPreferredSize(new java.awt.Dimension(600, 81)); - - sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel()); - sourceComboBox.setMaximumSize(new java.awt.Dimension(150, 32767)); - sourceComboBox.setMinimumSize(new java.awt.Dimension(150, 20)); - sourceComboBox.setPreferredSize(new java.awt.Dimension(150, 20)); - - jLabel1.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.jLabel1.text")); // NOI18N - - pageOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageOfLabel.text")); // NOI18N - - pageButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageButtonsLabel.text")); // NOI18N - - pageTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - pageTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageTotalLabel.text")); // NOI18N - - pagesLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagesLabel.text")); // NOI18N - - pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N - pageNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageNextButton.text")); // NOI18N - pageNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - pageNextButton.setBorderPainted(false); - pageNextButton.setContentAreaFilled(false); - pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N - pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - pageNextButton.setPreferredSize(new java.awt.Dimension(23, 23)); - - pagePreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N - pagePreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.text")); // NOI18N - pagePreviousButton.setActionCommand(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pagePreviousButton.actionCommand")); // NOI18N - pagePreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - pagePreviousButton.setBorderPainted(false); - pagePreviousButton.setContentAreaFilled(false); - pagePreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N - pagePreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - - pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N - - hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N - hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N - - hitButtonsLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitButtonsLabel.text")); // NOI18N - - hitNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward.png"))); // NOI18N - hitNextButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitNextButton.text")); // NOI18N - hitNextButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - hitNextButton.setBorderPainted(false); - hitNextButton.setContentAreaFilled(false); - hitNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_disabled.png"))); // NOI18N - hitNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - hitNextButton.setPreferredSize(new java.awt.Dimension(23, 23)); - hitNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_forward_hover.png"))); // NOI18N - - hitOfLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitOfLabel.text")); // NOI18N - - hitTotalLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - hitTotalLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitTotalLabel.text")); // NOI18N - hitTotalLabel.setMaximumSize(new java.awt.Dimension(18, 14)); - hitTotalLabel.setMinimumSize(new java.awt.Dimension(18, 14)); - hitTotalLabel.setPreferredSize(new java.awt.Dimension(18, 14)); - - hitPreviousButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back.png"))); // NOI18N - hitPreviousButton.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitPreviousButton.text")); // NOI18N - hitPreviousButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - hitPreviousButton.setBorderPainted(false); - hitPreviousButton.setContentAreaFilled(false); - hitPreviousButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_disabled.png"))); // NOI18N - hitPreviousButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - hitPreviousButton.setPreferredSize(new java.awt.Dimension(23, 23)); - hitPreviousButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/btn_step_back_hover.png"))); // NOI18N - - hitCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - hitCountLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitCountLabel.text")); // NOI18N - hitCountLabel.setMaximumSize(new java.awt.Dimension(18, 14)); - hitCountLabel.setMinimumSize(new java.awt.Dimension(18, 14)); - hitCountLabel.setPreferredSize(new java.awt.Dimension(18, 14)); - - jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); - - jSeparator3.setOrientation(javax.swing.SwingConstants.VERTICAL); - - zoomPanel.setMinimumSize(new java.awt.Dimension(150, 20)); - zoomPanel.setName(""); // NOI18N - zoomPanel.setPreferredSize(new java.awt.Dimension(200, 20)); - - javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); - controlPanel.setLayout(controlPanelLayout); - controlPanelLayout.setHorizontalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(hitLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hitOfLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(hitButtonsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(pagesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pageCurLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(pageOfLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pageTotalLabel) - .addGap(18, 18, 18) - .addComponent(pageButtonsLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pagePreviousButton) - .addGap(0, 0, 0) - .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - controlPanelLayout.setVerticalGroup( - controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) - .addComponent(hitPreviousButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1) - .addComponent(hitNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageButtonsLabel) - .addComponent(pagePreviousButton) - .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pagesLabel) - .addComponent(hitLabel) - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageCurLabel) - .addComponent(pageOfLabel) - .addComponent(hitCountLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageTotalLabel) - .addComponent(hitOfLabel) - .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(hitButtonsLabel) - .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(zoomPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0)) - ); - - controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox, zoomPanel}); - - zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N - - controlScrollPane.setViewportView(controlPanel); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 980, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 980, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) - ); + add(extractedScrollPane, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel controlPanel; - private javax.swing.JScrollPane controlScrollPane; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JScrollPane extractedScrollPane; private javax.swing.JTextPane extractedTextPane; @@ -440,6 +428,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private javax.swing.JLabel jLabel1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator3; + private javax.swing.JSeparator jSeparator4; private javax.swing.JLabel pageButtonsLabel; private javax.swing.JLabel pageCurLabel; private javax.swing.JButton pageNextButton; @@ -450,6 +439,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private javax.swing.JPopupMenu rightClickMenu; private javax.swing.JMenuItem selectAllMenuItem; private javax.swing.JComboBox sourceComboBox; + private javax.swing.JPanel textSourcePanel; private javax.swing.JPanel zoomPanel; // End of variables declaration//GEN-END:variables diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 46d8e3d66f..dc51c409c4 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -2,11 +2,15 @@
- - + + + + + + - + @@ -19,35 +23,13 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + @@ -125,18 +107,6 @@ - - - - - - - - - - - - diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index eb716df8df..79e433a858 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -113,11 +113,13 @@ class TextZoomPanel extends JPanel { zoomTextField = new javax.swing.JTextField(); zoomOutButton = new javax.swing.JButton(); zoomInButton = new javax.swing.JButton(); - javax.swing.JToolBar.Separator jSeparator2 = new javax.swing.JToolBar.Separator(); zoomResetButton = new javax.swing.JButton(); - setMinimumSize(new java.awt.Dimension(150, 20)); - setPreferredSize(new java.awt.Dimension(200, 20)); + setMaximumSize(null); + setMinimumSize(null); + setName(""); // NOI18N + setPreferredSize(null); + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); zoomTextField.setEditable(false); zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); @@ -125,6 +127,7 @@ class TextZoomPanel extends JPanel { zoomTextField.setMaximumSize(new java.awt.Dimension(50, 2147483647)); zoomTextField.setMinimumSize(new java.awt.Dimension(50, 20)); zoomTextField.setPreferredSize(new java.awt.Dimension(50, 20)); + add(zoomTextField); zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-out.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N @@ -140,6 +143,7 @@ class TextZoomPanel extends JPanel { zoomOutButtonActionPerformed(evt); } }); + add(zoomOutButton); zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-in.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N @@ -156,9 +160,7 @@ class TextZoomPanel extends JPanel { zoomInButtonActionPerformed(evt); } }); - - jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); - jSeparator2.setMaximumSize(new java.awt.Dimension(6, 20)); + add(zoomInButton); org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N zoomResetButton.setBorderPainted(false); @@ -172,31 +174,7 @@ class TextZoomPanel extends JPanel { zoomResetButtonActionPerformed(evt); } }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(zoomTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(zoomOutButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(zoomInButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(zoomResetButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(zoomTextField, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(zoomOutButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(zoomInButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(zoomResetButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + add(zoomResetButton); }// //GEN-END:initComponents private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed diff --git a/README.txt b/README.txt index 3ed2dda963..7917b66382 100644 --- a/README.txt +++ b/README.txt @@ -23,8 +23,6 @@ There is no need for manual installation of additional dependencies if the Windo If you want the Japanese localized version, you must have the Japanese language pack (http://support.microsoft.com/kb/972813) installed and the default locale set to JA. (http://windows.microsoft.com/en-us/windows/change-system-locale#1TC=windows-7). -Refer to the KNOWN_ISSUES.txt file for known bugs that could cause investigation problems. - SUPPORT @@ -151,4 +149,4 @@ WebHostingHub Glyphs - License: http://creativecommons.org/licenses/by/3.0/ Splashy Icons (free as in free) -- Web page: http://splashyfish.com/icons/ \ No newline at end of file +- Web page: http://splashyfish.com/icons/ diff --git a/Running_Linux_OSX.txt b/Running_Linux_OSX.txt index 521fa6e9f1..60b81bc50a 100644 --- a/Running_Linux_OSX.txt +++ b/Running_Linux_OSX.txt @@ -27,7 +27,7 @@ The following need to be done at least once. They do not need to be repeated for -- OS X: 1. Install BellSoft Java 8. % brew tap bell-sw/liberica - % brew cask install liberica-jdk8 + % brew cask install liberica-jdk8-full 2. Set JAVA_HOME environment variable to location of JRE installation. e.g. add the following to ~/.bashrc export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) @@ -80,6 +80,11 @@ Autopsy depends on a specific version of The Sleuth Kit. You need the Java libr (a) confirm that you have a version of Java 8 installed and (b) confirm that your JAVA_HOME environment variable is set correctly: % echo $JAVA_HOME + +- If you see something like "cannot be opened because the developer cannot be verified." it is an indication + that Gatekeeper is running and is stopping a file from being executed. To fix this open a new terminal window + and enter the following command "sudo spctl --master-disable", you will be required to enter your password. + This will allow any program to be be downloaded from anywhere and executed. * Limitations (Updated May 2018) * - Timeline does not work on OS X diff --git a/docs/doxygen/modDev.dox b/docs/doxygen/modDev.dox index a3195b74ed..2d8f1d313d 100644 --- a/docs/doxygen/modDev.dox +++ b/docs/doxygen/modDev.dox @@ -81,7 +81,7 @@ As you will read in the later sections about the different module types, each Au \subsection mod_dev_aut_run1 Running Your Module During Development -When you are developing your Autopsy module, you can simply choose "Run" on the module and it will launch the Autopsy platform with the module enabled in it. This is also how you can debug the module. +When you are developing your Autopsy module, you can simply choose "Run" on the module and it will launch the Autopsy platform with the module enabled in it. This is also how you can debug the module. If you want to apply changes during debugging and have not changed any method signatures, you can use the "Apply Code Changes" function in NetBeans. \subsection mod_dev_aut_deploy Deploying Your Module diff --git a/thirdparty/IcePDF 6.2.2/batik-awt-util-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-awt-util-1.6.jar new file mode 100755 index 0000000000..b62ac15866 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-awt-util-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/batik-dom-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-dom-1.6.jar new file mode 100755 index 0000000000..bf144ab070 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-dom-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/batik-svg-dom-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-svg-dom-1.6.jar new file mode 100755 index 0000000000..c8970fbb4d Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-svg-dom-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/batik-svggen-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-svggen-1.6.jar new file mode 100755 index 0000000000..819f2da07a Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-svggen-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/batik-util-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-util-1.6.jar new file mode 100755 index 0000000000..7550b4802e Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-util-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/batik-xml-1.6.jar b/thirdparty/IcePDF 6.2.2/batik-xml-1.6.jar new file mode 100755 index 0000000000..1b915a0503 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/batik-xml-1.6.jar differ diff --git a/thirdparty/IcePDF 6.2.2/bcpkix-jdk15on-1.54.jar b/thirdparty/IcePDF 6.2.2/bcpkix-jdk15on-1.54.jar new file mode 100755 index 0000000000..86f7f0be19 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/bcpkix-jdk15on-1.54.jar differ diff --git a/thirdparty/IcePDF 6.2.2/bcprov-ext-jdk15on-1.54.jar b/thirdparty/IcePDF 6.2.2/bcprov-ext-jdk15on-1.54.jar new file mode 100755 index 0000000000..f31c1c1c45 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/bcprov-ext-jdk15on-1.54.jar differ diff --git a/thirdparty/IcePDF 6.2.2/bcprov-jdk15on-1.54.jar b/thirdparty/IcePDF 6.2.2/bcprov-jdk15on-1.54.jar new file mode 100755 index 0000000000..bd95185ae8 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/bcprov-jdk15on-1.54.jar differ diff --git a/thirdparty/IcePDF 6.2.2/icepdf-core-6.2.2.jar b/thirdparty/IcePDF 6.2.2/icepdf-core-6.2.2.jar new file mode 100755 index 0000000000..b5555280e1 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/icepdf-core-6.2.2.jar differ diff --git a/thirdparty/IcePDF 6.2.2/icepdf-viewer-6.2.2.jar b/thirdparty/IcePDF 6.2.2/icepdf-viewer-6.2.2.jar new file mode 100755 index 0000000000..d58fcc9de3 Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/icepdf-viewer-6.2.2.jar differ diff --git a/thirdparty/IcePDF 6.2.2/jai_core-1.1.3.jar b/thirdparty/IcePDF 6.2.2/jai_core-1.1.3.jar new file mode 100755 index 0000000000..b29b8eed5b Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/jai_core-1.1.3.jar differ diff --git a/thirdparty/IcePDF 6.2.2/jai_imageio-1.1.jar b/thirdparty/IcePDF 6.2.2/jai_imageio-1.1.jar new file mode 100755 index 0000000000..571aa199fa Binary files /dev/null and b/thirdparty/IcePDF 6.2.2/jai_imageio-1.1.jar differ