diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index fce437a96f..caa5ecd386 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -147,3 +147,7 @@ AutopsyOptionsPanel.jLabelNumThreads.text=Number of threads to use for file inge FXVideoPanel.progress.bufferingCancelled=media buffering was canceled FXVideoPanel.progress.bufferingInterrupted=media buffering was interrupted FXVideoPanel.progress.errorWritingVideoToDisk=Error writing video to disk +DataContentViewerHex.goToOffsetLabel.text=Jump to Offset +DataContentViewerHex.goToOffsetTextField.text= +DataContentViewerHex.goToOffsetTextField.msgDlg=Invalid Offset: {0} +DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue=Cannot jump to the resultant offset \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form index a5663b4644..cd5d9e21d0 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form @@ -88,9 +88,13 @@ - + + + + + - + @@ -108,9 +112,11 @@ + + - - + + @@ -131,6 +137,9 @@ + + + @@ -140,7 +149,7 @@ - + @@ -278,6 +287,23 @@ + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java index c7eb83ebd0..11cee38ab4 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java @@ -28,6 +28,8 @@ import org.sleuthkit.autopsy.coreutils.Logger; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JTextPane; +import javax.swing.text.BadLocationException; +import javax.swing.text.Utilities; import org.openide.nodes.Node; import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; @@ -94,6 +96,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont return (getSize().width < 400); }}; this.outputViewPane.setBackground(new java.awt.Color(255, 255, 255)); // to make sure the background color is white + this.outputViewPane.requestFocusInWindow(); + this.outputViewPane.setCursor(Cursor.getDefaultCursor()); totalPageLabel = new javax.swing.JLabel(); ofLabel = new javax.swing.JLabel(); currentPageLabel = new javax.swing.JLabel(); @@ -103,6 +107,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont pageLabel2 = new javax.swing.JLabel(); goToPageTextField = new javax.swing.JTextField(); goToPageLabel = new javax.swing.JLabel(); + goToOffsetLabel = new javax.swing.JLabel(); + goToOffsetTextField = new javax.swing.JTextField(); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.copyMenuItem.text")); // NOI18N rightClickMenu.add(copyMenuItem); @@ -113,7 +119,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont jScrollPane1.setBackground(new java.awt.Color(255, 255, 255)); outputViewPane.setEditable(false); - outputViewPane.setFont(new Font("Courier New", Font.PLAIN, 11)); // NOI18N NON-NLS + outputViewPane.setFont(new java.awt.Font("Courier New", 0, 11)); // NOI18N + outputViewPane.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); outputViewPane.setMinimumSize(new java.awt.Dimension(700, 20)); outputViewPane.setPreferredSize(new java.awt.Dimension(700, 400)); jScrollPane1.setViewportView(outputViewPane); @@ -132,28 +139,28 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont pageLabel.setMinimumSize(new java.awt.Dimension(33, 14)); pageLabel.setPreferredSize(new java.awt.Dimension(33, 14)); - prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N NON-NLS + prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.prevPageButton.text")); // NOI18N prevPageButton.setBorderPainted(false); prevPageButton.setContentAreaFilled(false); - prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N NON-NLS + 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(23, 23)); - prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N NON-NLS + 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); } }); - nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N NON-NLS + nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.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 NON-NLS + 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(23, 23)); - nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N NON-NLS + 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); @@ -174,6 +181,15 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont goToPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToPageLabel.text")); // NOI18N + goToOffsetLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetLabel.text")); // NOI18N + + goToOffsetTextField.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetTextField.text")); // NOI18N + goToOffsetTextField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + goToOffsetTextFieldActionPerformed(evt); + } + }); + javax.swing.GroupLayout hexViewerPanelLayout = new javax.swing.GroupLayout(hexViewerPanel); hexViewerPanel.setLayout(hexViewerPanelLayout); hexViewerPanelLayout.setHorizontalGroup( @@ -197,8 +213,12 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont .addComponent(goToPageLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(205, Short.MAX_VALUE)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE) + .addGap(18, 18, 18) + .addComponent(goToOffsetLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane1) ); hexViewerPanelLayout.setVerticalGroup( hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -213,9 +233,11 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont .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) - .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)) + .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(goToOffsetLabel) + .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -241,11 +263,13 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont }// //GEN-END:initComponents private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed - setDataView(currentPage - 1); + setDataViewByPageNumber(currentPage - 1); + goToPageTextField.setText(Integer.toString(currentPage)); }//GEN-LAST:event_prevPageButtonActionPerformed private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed - setDataView(currentPage + 1); + setDataViewByPageNumber(currentPage + 1); + goToPageTextField.setText(Integer.toString(currentPage)); }//GEN-LAST:event_nextPageButtonActionPerformed private void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageTextFieldActionPerformed @@ -267,11 +291,59 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont JOptionPane.WARNING_MESSAGE); return; } - setDataView(pageNumber); + setDataViewByPageNumber(pageNumber); }//GEN-LAST:event_goToPageTextFieldActionPerformed + + /*** + * Calculates the offset relative to the current caret position. + * @param userInput the user provided signed offset value. + * @return returns the resultant offset value relative to the current caret + * position. -1L is returned if the resultant offset cannot be calculated. + */ + private long getOffsetRelativeToCaretPosition(Long userInput) { + String userSelectedLine; + try { + // get the selected line. Extract the current hex offset location. + userSelectedLine = outputViewPane.getText().subSequence( + Utilities.getRowStart(outputViewPane, outputViewPane.getCaretPosition()), + Utilities.getRowEnd(outputViewPane, outputViewPane.getCaretPosition())) + .toString(); + // NOTE: This needs to change if the outputFormat of outputViewPane changes. + String hexForUserSelectedLine = userSelectedLine.substring(0, userSelectedLine.indexOf(":")); + + return Long.decode(hexForUserSelectedLine) + userInput; + } catch (BadLocationException | StringIndexOutOfBoundsException | NumberFormatException ex) { + // thrown in case the caret location is out of the range of the outputViewPane. + return -1L; + } + } + + private void goToOffsetTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToOffsetTextFieldActionPerformed + long offset; + try { + if (goToOffsetTextField.getText().startsWith("+") || goToOffsetTextField.getText().startsWith("-")) { + offset = getOffsetRelativeToCaretPosition(Long.decode(goToOffsetTextField.getText())); + } else { + offset = Long.decode(goToOffsetTextField.getText()); + } + } catch (NumberFormatException ex) { + // notify the user and return + JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), "DataContentViewerHex.goToOffsetTextField.msgDlg", goToOffsetTextField.getText())); + return; + } + + if (offset >= 0) { + setDataViewByOffset(offset); + } else { + outputViewPane.setText(NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue")); + } + }//GEN-LAST:event_goToOffsetTextFieldActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenuItem copyMenuItem; private javax.swing.JLabel currentPageLabel; + private javax.swing.JLabel goToOffsetLabel; + private javax.swing.JTextField goToOffsetTextField; private javax.swing.JLabel goToPageLabel; private javax.swing.JTextField goToPageTextField; private javax.swing.JPanel hexViewerPanel; @@ -289,26 +361,41 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont /** - * Sets the DataView (The tabbed panel) + * Sets the DataView (The tabbed panel) by page number * * @param page Page to display (1-based counting) */ - private void setDataView(int page) { + private void setDataViewByPageNumber(int page) { if (this.dataSource == null) { return; } - if (page == 0) { return; } - currentPage = page; long offset = (currentPage - 1) * pageLength; - + setDataView(offset); + goToOffsetTextField.setText(Long.toString(offset)); + } + /** + * Sets the DataView (The tabbed panel) by offset + * + * @param page Page to display (1-based counting) + */ + private void setDataViewByOffset(long offset) { + if (this.dataSource == null) { + return; + } + currentPage = (int) (offset / pageLength) + 1; + setDataView(offset); + goToPageTextField.setText(Integer.toString(currentPage)); + } + + private void setDataView(long offset) { // change the cursor to "waiting cursor" for this operation this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - String errorText = null; + String errorText = null; int bytesRead = 0; if (dataSource.getSize() > 0) { @@ -316,7 +403,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont bytesRead = dataSource.read(data, offset, pageLength); // read the data } catch (TskException ex) { errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset, - offset + pageLength); + offset + pageLength); logger.log(Level.WARNING, "Error while trying to show the hex content.", ex); //NON-NLS } } @@ -324,25 +411,22 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont // set the data on the bottom and show it if (bytesRead <= 0) { errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset, - offset + pageLength); + offset + pageLength); } - // disable or enable the next button if ((errorText == null) && (currentPage < totalPages)) { nextPageButton.setEnabled(true); - } - else { + } else { nextPageButton.setEnabled(false); } if ((errorText == null) && (currentPage > 1)) { prevPageButton.setEnabled(true); - } - else { + } else { prevPageButton.setEnabled(false); } - + currentPageLabel.setText(Integer.toString(currentPage)); setComponentsVisibility(true); // shows the components that not needed @@ -350,8 +434,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont if (errorText == null) { int showLength = bytesRead < pageLength ? bytesRead : (int) pageLength; outputViewPane.setText(DataConversion.byteArrayToHex(data, showLength, offset)); - } - else { + } else { outputViewPane.setText(errorText); } @@ -379,7 +462,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont } totalPageLabel.setText(Integer.toString(totalPages)); - this.setDataView(1); + this.setDataViewByPageNumber(1); } @Override @@ -423,6 +506,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont pageLabel2.setVisible(isVisible); goToPageTextField.setVisible(isVisible); goToPageLabel.setVisible(isVisible); + goToOffsetTextField.setVisible(isVisible); + goToOffsetLabel.setVisible(isVisible); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java index c0c1e970b8..fe2e9d66f2 100755 --- a/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java +++ b/Core/src/org/sleuthkit/autopsy/python/JythonModuleLoader.java @@ -120,7 +120,7 @@ public final class JythonModuleLoader { interpreter.exec("import sys"); //NON-NLS String path = Matcher.quoteReplacement(script.getParent()); interpreter.exec("sys.path.append('" + path + "')"); //NON-NLS - String moduleName = script.getName().replaceAll(".py", ""); //NON-NLS + String moduleName = script.getName().replaceAll("\\.py$", ""); //NON-NLS // reload the module so that the changes made to it can be loaded. interpreter.exec("import " + moduleName); //NON-NLS diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java index 7047d5291a..9d713ac3e8 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java @@ -34,6 +34,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; @@ -1196,10 +1197,23 @@ public final class DrawableDB { /** * For performance reasons, keep the file type in memory */ - private final Map videoFileMap = new ConcurrentHashMap<>(); + private final Map videoFileMap = new ConcurrentHashMap<>(); + /** + * is this File a video file? + * + * @param f check if this file is a video. will return false for null file. + * + * @return returns true if this file is a video as determined by {@link ImageGalleryModule#isVideoFile(org.sleuthkit.datamodel.AbstractFile) + * } but caches the result. + * returns false if passed a null AbstractFile + */ public boolean isVideoFile(AbstractFile f) { - return videoFileMap.computeIfAbsent(f, FileTypeUtils::isVideoFile); + if (Objects.isNull(f)) { + return false; + } else { + return videoFileMap.computeIfAbsent(f.getId(), (id) -> ImageGalleryModule.isVideoFile(f)); + } } /** diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTileBase.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTileBase.java index ed12891589..631e43aea6 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTileBase.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableTileBase.java @@ -284,7 +284,7 @@ public abstract class DrawableTileBase extends DrawableUIBase { } @Override - protected void setFileHelper(final Long newFileID) { + synchronized protected void setFileHelper(final Long newFileID) { setFileIDOpt(Optional.ofNullable(newFileID)); disposeContent(); @@ -351,7 +351,6 @@ public abstract class DrawableTileBase extends DrawableUIBase { @Subscribe @Override public void handleTagAdded(ContentTagAddedEvent evt) { - handleTagEvent(evt, () -> { Platform.runLater(() -> { followUpImageView.setImage(followUpIcon); diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java index 0657385aff..267632ed85 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java @@ -35,9 +35,9 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView private final ImageGalleryController controller; - volatile private Optional> fileOpt = Optional.empty(); + private Optional> fileOpt = Optional.empty(); - volatile private Optional fileIDOpt = Optional.empty(); + private Optional fileIDOpt = Optional.empty(); public DrawableUIBase(ImageGalleryController controller) { this.controller = controller; @@ -53,16 +53,16 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView return fileIDOpt; } - void setFileIDOpt(Optional fileIDOpt) { + synchronized void setFileIDOpt(Optional fileIDOpt) { this.fileIDOpt = fileIDOpt; } - void setFileOpt(Optional> fileOpt) { + synchronized void setFileOpt(Optional> fileOpt) { this.fileOpt = fileOpt; } @Override - public Optional> getFile() { + synchronized public Optional> getFile() { if (fileIDOpt.isPresent()) { if (fileOpt.isPresent() && fileOpt.get().getId() == fileIDOpt.get()) { return fileOpt; @@ -83,7 +83,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView protected abstract void setFileHelper(Long newFileID); @Override - public void setFile(Long newFileID) { + synchronized public void setFile(Long newFileID) { if (getFileID().isPresent()) { if (Objects.equals(newFileID, getFileID().get()) == false) { setFileHelper(newFileID); @@ -92,6 +92,4 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView setFileHelper(newFileID); } } - - } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java index 0f3f2c5b62..9e544c031c 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java @@ -150,7 +150,7 @@ public class MetaDataPane extends DrawableUIBase { } @Override - protected synchronized void setFileHelper(Long newFileID) { + synchronized protected void setFileHelper(Long newFileID) { setFileIDOpt(Optional.ofNullable(newFileID)); if (newFileID == null) { Platform.runLater(() -> { diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java index 2b29e57d39..412c641ad4 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/SlideShowView.java @@ -290,7 +290,7 @@ public class SlideShowView extends DrawableTileBase { * 1 => right / forward */ @ThreadConfined(type = ThreadType.JFX) - private void cycleSlideShowImage(int direction) { + synchronized private void cycleSlideShowImage(int direction) { stopVideo(); final int groupSize = getGroupPane().getGrouping().fileIds().size(); final Integer nextIndex = getFileID().map(fileID -> { @@ -363,7 +363,6 @@ public class SlideShowView extends DrawableTileBase { new CategorizeAction(getController()).addTag(getController().getTagsManager().getTagName(cat), ""); } }); - } } } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/GroupTreeCell.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/GroupTreeCell.java index 8103a55cf6..8618634aab 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/GroupTreeCell.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/GroupTreeCell.java @@ -107,7 +107,6 @@ class GroupTreeCell extends TreeCell { setStyle(""); }); } else { - if (isNull(treeNode.getGroup())) { final String groupName = getGroupName(); //"dummy" group in file system tree <=> a folder with no drawables @@ -141,7 +140,7 @@ class GroupTreeCell extends TreeCell { private String getGroupName() { return Optional.ofNullable(getItem()) - .map((TreeNode t) -> StringUtils.defaultIfBlank(t.getPath(), DrawableGroup.getBlankGroupName())) + .map(treeNode -> StringUtils.defaultIfBlank(treeNode.getPath(), DrawableGroup.getBlankGroupName())) .orElse(""); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/NavPanel.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/NavPanel.java index 64aa5a681e..d00f28cea8 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/NavPanel.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/navpanel/NavPanel.java @@ -28,7 +28,6 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.ComboBox; import javafx.scene.control.ListView; @@ -151,13 +150,15 @@ public class NavPanel extends TabPane { } }); - initHashTree(); - initNavTree(); - controller.getGroupManager().getAnalyzedGroups().addListener((ListChangeListener.Change change) -> { TreeItem selectedItem = activeTreeProperty.get().getSelectionModel().getSelectedItem(); boolean wasPermuted = false; while (change.next()) { + if (change.wasPermutated()) { + // Handle this afterward + wasPermuted = true; + break; + } for (DrawableGroup g : change.getAddedSubList()) { insertIntoNavTree(g); if (g.getHashSetHitsCount() > 0) { @@ -168,11 +169,6 @@ public class NavPanel extends TabPane { removeFromNavTree(g); removeFromHashTree(g); } - if (change.wasPermutated()) { - // Handle this afterward - wasPermuted = true; - break; - } } if (wasPermuted) { @@ -182,16 +178,10 @@ public class NavPanel extends TabPane { Platform.runLater(() -> { setFocusedGroup(selectedItem.getValue().getGroup()); }); - } }); - for (DrawableGroup g : controller.getGroupManager().getAnalyzedGroups()) { - insertIntoNavTree(g); - if (g.getHashSetHitsCount() > 0) { - insertIntoHashTree(g); - } - } + rebuildTrees(); controller.viewState().addListener((ObservableValue observable, GroupViewState oldValue, GroupViewState newValue) -> { if (newValue != null && newValue.getGroup() != null) { @@ -204,9 +194,7 @@ public class NavPanel extends TabPane { navTreeRoot = new GroupTreeItem("", null, sortByBox.getSelectionModel().selectedItemProperty().get()); hashTreeRoot = new GroupTreeItem("", null, sortByBox.getSelectionModel().selectedItemProperty().get()); - ObservableList groups = controller.getGroupManager().getAnalyzedGroups(); - - for (DrawableGroup g : groups) { + for (DrawableGroup g : controller.getGroupManager().getAnalyzedGroups()) { insertIntoNavTree(g); if (g.getHashSetHitsCount() > 0) { insertIntoHashTree(g);