mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merge pull request #6244 from rcordovano/6807-MediaViewImagePanel-thread-safety
6807 Tidy up MediaViewImagePanel
This commit is contained in:
commit
38a64fb558
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2019 Basis Technology Corp.
|
* Copyright 2018-2020 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -97,68 +97,70 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* Image viewer part of the Media View layered pane. Uses JavaFX to display the
|
* Image viewer part of the Media View layered pane. Uses JavaFX to display the
|
||||||
* image.
|
* image.
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E",
|
@NbBundle.Messages({
|
||||||
|
"MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E",
|
||||||
"MediaViewImagePanel.errorLabel.text=Could not load file into Media View.",
|
"MediaViewImagePanel.errorLabel.text=Could not load file into Media View.",
|
||||||
"MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory."})
|
"MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory."
|
||||||
|
})
|
||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPanel {
|
class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPanel {
|
||||||
|
|
||||||
private static final Image EXTERNAL = new Image(MediaViewImagePanel.class.getResource("/org/sleuthkit/autopsy/images/external.png").toExternalForm());
|
private static final long serialVersionUID = 1L;
|
||||||
private final static Logger LOGGER = Logger.getLogger(MediaViewImagePanel.class.getName());
|
private static final Logger logger = Logger.getLogger(MediaViewImagePanel.class.getName());
|
||||||
|
private static final double[] ZOOM_STEPS = {
|
||||||
|
0.0625, 0.125, 0.25, 0.375, 0.5, 0.75,
|
||||||
|
1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10};
|
||||||
|
private static final double MIN_ZOOM_RATIO = 0.0625; // 6.25%
|
||||||
|
private static final double MAX_ZOOM_RATIO = 10.0; // 1000%
|
||||||
|
private static final Image externalImage = new Image(MediaViewImagePanel.class.getResource("/org/sleuthkit/autopsy/images/external.png").toExternalForm());
|
||||||
|
private static final SortedSet<String> supportedMimes = ImageUtils.getSupportedImageMimeTypes();
|
||||||
|
private static final List<String> supportedExtensions = ImageUtils.getSupportedImageExtensions().stream()
|
||||||
|
.map("."::concat) //NOI18N
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
private final boolean fxInited;
|
private final boolean fxInited;
|
||||||
|
|
||||||
private JFXPanel fxPanel;
|
/*
|
||||||
private AbstractFile file;
|
* JFX
|
||||||
private Group masterGroup;
|
*/
|
||||||
private ImageTagsGroup tagsGroup;
|
|
||||||
private ImageTagCreator imageTagCreator;
|
|
||||||
private ImageView fxImageView;
|
|
||||||
private ScrollPane scrollPane;
|
|
||||||
private final ProgressBar progressBar = new ProgressBar();
|
private final ProgressBar progressBar = new ProgressBar();
|
||||||
private final MaskerPane maskerPane = new MaskerPane();
|
private final MaskerPane maskerPane = new MaskerPane();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swing
|
||||||
|
*/
|
||||||
private final JPopupMenu imageTaggingOptions = new JPopupMenu();
|
private final JPopupMenu imageTaggingOptions = new JPopupMenu();
|
||||||
private final JMenuItem createTagMenuItem;
|
private final JMenuItem createTagMenuItem;
|
||||||
private final JMenuItem deleteTagMenuItem;
|
private final JMenuItem deleteTagMenuItem;
|
||||||
private final JMenuItem hideTagsMenuItem;
|
private final JMenuItem hideTagsMenuItem;
|
||||||
private final JMenuItem exportTagsMenuItem;
|
private final JMenuItem exportTagsMenuItem;
|
||||||
|
|
||||||
private final JFileChooser exportChooser;
|
private final JFileChooser exportChooser;
|
||||||
|
|
||||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JFX
|
||||||
|
*/
|
||||||
|
private Group masterGroup;
|
||||||
|
private ImageTagsGroup tagsGroup;
|
||||||
|
private ImageTagCreator imageTagCreator;
|
||||||
|
private ImageView fxImageView;
|
||||||
|
private ScrollPane scrollPane;
|
||||||
|
private Task<Image> readImageTask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swing
|
||||||
|
*/
|
||||||
|
private JFXPanel fxPanel;
|
||||||
|
|
||||||
private double zoomRatio;
|
private double zoomRatio;
|
||||||
private double rotation; // Can be 0, 90, 180, and 270.
|
private double rotation; // Can be 0, 90, 180, and 270.
|
||||||
|
private boolean autoResize = true; // Auto resize when the user changes the size of the content viewer unless the user has used the zoom buttons.
|
||||||
private boolean autoResize = true; // Auto resize when the user changes the size
|
private AbstractFile file;
|
||||||
// of the content viewer unless the user has used the zoom buttons.
|
|
||||||
private static final double[] ZOOM_STEPS = {
|
|
||||||
0.0625, 0.125, 0.25, 0.375, 0.5, 0.75,
|
|
||||||
1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10};
|
|
||||||
|
|
||||||
private static final double MIN_ZOOM_RATIO = 0.0625; // 6.25%
|
|
||||||
private static final double MAX_ZOOM_RATIO = 10.0; // 1000%
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ImageIO.scanForPlugins();
|
ImageIO.scanForPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* mime types we should be able to display. if the mimetype is unknown we
|
|
||||||
* will fall back on extension and jpg/png header
|
|
||||||
*/
|
|
||||||
static private final SortedSet<String> supportedMimes = ImageUtils.getSupportedImageMimeTypes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* extensions we should be able to display
|
|
||||||
*/
|
|
||||||
static private final List<String> supportedExtensions = ImageUtils.getSupportedImageExtensions().stream()
|
|
||||||
.map("."::concat) //NOI18N
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
private Task<Image> readImageTask;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form MediaViewImagePanel
|
* Creates new form MediaViewImagePanel
|
||||||
*/
|
*/
|
||||||
@ -168,7 +170,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
"MediaViewImagePanel.hideTagOption=Hide",
|
"MediaViewImagePanel.hideTagOption=Hide",
|
||||||
"MediaViewImagePanel.exportTagOption=Export"
|
"MediaViewImagePanel.exportTagOption=Export"
|
||||||
})
|
})
|
||||||
public MediaViewImagePanel() {
|
MediaViewImagePanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
fxInited = org.sleuthkit.autopsy.core.Installer.isJavaFxInited();
|
fxInited = org.sleuthkit.autopsy.core.Installer.isJavaFxInited();
|
||||||
|
|
||||||
@ -354,14 +356,13 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorNode(String errorMessage, AbstractFile file) {
|
private void showErrorNode(String errorMessage, AbstractFile file) {
|
||||||
final Button externalViewerButton = new Button(Bundle.MediaViewImagePanel_externalViewerButton_text(), new ImageView(EXTERNAL));
|
final Button externalViewerButton = new Button(Bundle.MediaViewImagePanel_externalViewerButton_text(), new ImageView(externalImage));
|
||||||
externalViewerButton.setOnAction(actionEvent
|
|
||||||
-> //fx ActionEvent
|
|
||||||
/*
|
/*
|
||||||
* TODO: why is the name passed into the action constructor? it
|
* Tie a Swing action (ExternalViewerAction) to a JFX button action.
|
||||||
* means we duplicate this string all over the place -jm
|
*/
|
||||||
*/ new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file))
|
externalViewerButton.setOnAction(actionEvent ->
|
||||||
.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "")) //Swing ActionEvent
|
new ExternalViewerAction(Bundle.MediaViewImagePanel_externalViewerButton_text(), new FileNode(file))
|
||||||
|
.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ""))
|
||||||
);
|
);
|
||||||
|
|
||||||
final VBox errorNode = new VBox(10, new Label(errorMessage), externalViewerButton);
|
final VBox errorNode = new VBox(10, new Label(errorMessage), externalViewerButton);
|
||||||
@ -420,7 +421,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
"state", null, State.NONEMPTY));
|
"state", null, State.NONEMPTY));
|
||||||
}
|
}
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Could not retrieve image tags for file in case db", ex); //NON-NLS
|
logger.log(Level.WARNING, "Could not retrieve image tags for file in case db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
scrollPane.setContent(masterGroup);
|
scrollPane.setContent(masterGroup);
|
||||||
} else {
|
} else {
|
||||||
@ -760,7 +761,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
Case.getCurrentCase().getServices().getTagsManager().deleteContentTag(contentViewerTag.getContentTag());
|
Case.getCurrentCase().getServices().getTagsManager().deleteContentTag(contentViewerTag.getContentTag());
|
||||||
tagsGroup.getChildren().remove(tagInFocus);
|
tagsGroup.getChildren().remove(tagInFocus);
|
||||||
} catch (TskCoreException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | NoCurrentCaseException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Could not delete image tag in case db", ex); //NON-NLS
|
logger.log(Level.WARNING, "Could not delete image tag in case db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollPane.setCursor(Cursor.DEFAULT);
|
scrollPane.setCursor(Cursor.DEFAULT);
|
||||||
@ -793,7 +794,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
ImageTag imageTag = buildImageTag(contentViewerTag);
|
ImageTag imageTag = buildImageTag(contentViewerTag);
|
||||||
tagsGroup.getChildren().add(imageTag);
|
tagsGroup.getChildren().add(imageTag);
|
||||||
} catch (TskCoreException | SerializationException | NoCurrentCaseException ex) {
|
} catch (TskCoreException | SerializationException | NoCurrentCaseException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Could not save new image tag in case db", ex); //NON-NLS
|
logger.log(Level.WARNING, "Could not save new image tag in case db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollPane.setCursor(Cursor.DEFAULT);
|
scrollPane.setCursor(Cursor.DEFAULT);
|
||||||
@ -832,7 +833,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
ImageTagRegion newRegion = (ImageTagRegion) edit.getNewValue();
|
ImageTagRegion newRegion = (ImageTagRegion) edit.getNewValue();
|
||||||
ContentViewerTagManager.updateTag(contentViewerTag, newRegion);
|
ContentViewerTagManager.updateTag(contentViewerTag, newRegion);
|
||||||
} catch (SerializationException | TskCoreException | NoCurrentCaseException ex) {
|
} catch (SerializationException | TskCoreException | NoCurrentCaseException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Could not save edit for image tag in case db", ex); //NON-NLS
|
logger.log(Level.WARNING, "Could not save edit for image tag in case db", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
scrollPane.setCursor(Cursor.DEFAULT);
|
scrollPane.setCursor(Cursor.DEFAULT);
|
||||||
});
|
});
|
||||||
@ -916,7 +917,7 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
JOptionPane.showMessageDialog(null, Bundle.MediaViewImagePanel_successfulExport());
|
JOptionPane.showMessageDialog(null, Bundle.MediaViewImagePanel_successfulExport());
|
||||||
} catch (Exception ex) { //Runtime exceptions may spill out of ImageTagsUtil from JavaFX.
|
} catch (Exception ex) { //Runtime exceptions may spill out of ImageTagsUtil from JavaFX.
|
||||||
//This ensures we (devs and users) have something when it doesn't work.
|
//This ensures we (devs and users) have something when it doesn't work.
|
||||||
LOGGER.log(Level.WARNING, "Unable to export tagged image to disk", ex); //NON-NLS
|
logger.log(Level.WARNING, "Unable to export tagged image to disk", ex); //NON-NLS
|
||||||
JOptionPane.showMessageDialog(null, Bundle.MediaViewImagePanel_unsuccessfulExport());
|
JOptionPane.showMessageDialog(null, Bundle.MediaViewImagePanel_unsuccessfulExport());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user