mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Merge pull request #119 from tmciver-basis/master
Changes to DataContentViewerMedia for thread issues
This commit is contained in:
commit
f5e6ec64f4
@ -52,6 +52,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
||||
private boolean isDefault;
|
||||
// Different DataContentViewers
|
||||
private List<UpdateWrapper> viewers = new ArrayList<UpdateWrapper>();
|
||||
|
||||
// contains a list of the undocked TCs
|
||||
private static ArrayList<DataContentTopComponent> newWindowList = new ArrayList<DataContentTopComponent>();
|
||||
private static final String PREFERRED_ID = "DataContentTopComponent";
|
||||
@ -291,34 +292,22 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
||||
*/
|
||||
public void setupTabs(Node selectedNode) {
|
||||
|
||||
int currTabIndex = dataContentTabbedPane.getSelectedIndex();
|
||||
int totalTabs = dataContentTabbedPane.getTabCount();
|
||||
|
||||
int maxPreferred = 0;
|
||||
int indexOfPreferred = 0;
|
||||
for (int i = 0; i < totalTabs; ++i) {
|
||||
UpdateWrapper dcv = viewers.get(i);
|
||||
dcv.resetComponent();
|
||||
|
||||
if (totalTabs > 0) { // make sure there are tabs to reset
|
||||
for (int i = 0; i < totalTabs; i++) {
|
||||
UpdateWrapper dcv = viewers.get(i);
|
||||
dcv.resetComponent();
|
||||
|
||||
// disable an unsupported tab (ex: picture viewer)
|
||||
boolean dcvSupported = dcv.isSupported(selectedNode);
|
||||
if (! dcvSupported) {
|
||||
dataContentTabbedPane.setEnabledAt(i, false);
|
||||
} else {
|
||||
dataContentTabbedPane.setEnabledAt(i, true);
|
||||
int currentPreferred = dcv.isPreferred(selectedNode, dcvSupported);
|
||||
if (currentPreferred > maxPreferred) {
|
||||
indexOfPreferred = i;
|
||||
maxPreferred = currentPreferred;
|
||||
}
|
||||
|
||||
}
|
||||
// disable an unsupported tab (ex: picture viewer)
|
||||
boolean dcvSupported = dcv.isSupported(selectedNode);
|
||||
if (!dcvSupported) {
|
||||
dataContentTabbedPane.setEnabledAt(i, false);
|
||||
} else {
|
||||
dataContentTabbedPane.setEnabledAt(i, true);
|
||||
}
|
||||
// set the display of the tab
|
||||
dataContentTabbedPane.setSelectedIndex(indexOfPreferred);
|
||||
viewers.get(indexOfPreferred).setNode(selectedNode);
|
||||
}
|
||||
|
||||
viewers.get(currTabIndex).setNode(selectedNode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
@ -59,6 +60,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
private long durationMillis = 0;
|
||||
private boolean autoTracking = false; // true if the slider is moving automatically
|
||||
private final Object playbinLock = new Object(); // lock for synchronization of playbin2 player
|
||||
private VideoProgressWorker videoProgressWorker;
|
||||
|
||||
/**
|
||||
* Creates new form DataContentViewerVideo
|
||||
@ -186,6 +188,12 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
if (selectedNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get rid of any existing videoProgressWorker thread
|
||||
if (videoProgressWorker != null) {
|
||||
videoProgressWorker.cancel(true);
|
||||
videoProgressWorker = null;
|
||||
}
|
||||
|
||||
File file = selectedNode.getLookup().lookup(File.class);
|
||||
if (file == null) {
|
||||
@ -303,15 +311,19 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
// reset the progress label text on the event dispatch thread
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressLabel.setText(" ");
|
||||
}
|
||||
});
|
||||
synchronized (playbinLock) {
|
||||
if (playbin2 != null) {
|
||||
if (playbin2.isPlaying()) {
|
||||
playbin2.stop();
|
||||
}
|
||||
playbin2.setState(State.NULL);
|
||||
// try {
|
||||
// Thread.sleep(20); // gstreamer needs to catch up
|
||||
// } catch (InterruptedException ex) { }
|
||||
if (playbin2.getState().equals(State.NULL)) {
|
||||
playbin2.dispose();
|
||||
}
|
||||
@ -397,8 +409,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
this.jFile = jFile;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
success = false;
|
||||
@ -444,7 +454,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
progressLabel.setText("Error buffering file");
|
||||
return;
|
||||
}
|
||||
ClockTime dur = null;
|
||||
ClockTime dur = null;
|
||||
synchronized (playbinLock) {
|
||||
playbin2.play(); // must play, then pause and get state to get duration.
|
||||
playbin2.pause();
|
||||
@ -454,73 +464,97 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
duration = dur.toString();
|
||||
durationMillis = dur.toMillis();
|
||||
|
||||
progressSlider.setMaximum((int) durationMillis);
|
||||
progressSlider.setMinimum(0);
|
||||
final String finalDuration;
|
||||
if (duration.length() == 8 && duration.substring(0, 3).equals("00:")) {
|
||||
finalDuration = duration.substring(3);
|
||||
progressLabel.setText("00:00/" + duration);
|
||||
} else {
|
||||
finalDuration = duration;
|
||||
progressLabel.setText("00:00:00/" + duration);
|
||||
}
|
||||
synchronized (playbinLock) {
|
||||
playbin2.play();
|
||||
}
|
||||
pauseButton.setText("||");
|
||||
new Thread(new Runnable() {
|
||||
private boolean isPlayBinReady() {
|
||||
synchronized (playbinLock) {
|
||||
return playbin2 != null && !playbin2.getState().equals(State.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long positionMillis = 0;
|
||||
while (positionMillis < durationMillis
|
||||
&& isPlayBinReady() ) {
|
||||
ClockTime pos = null;
|
||||
synchronized (playbinLock) {
|
||||
pos = playbin2.queryPosition();
|
||||
}
|
||||
position = pos.toString();
|
||||
positionMillis = pos.toMillis();
|
||||
|
||||
if (position.length() == 8) {
|
||||
position = position.substring(3);
|
||||
}
|
||||
progressLabel.setText(position + "/" + finalDuration);
|
||||
autoTracking = true;
|
||||
progressSlider.setValue((int) positionMillis);
|
||||
autoTracking = false;
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
if (finalDuration.length() == 5) {
|
||||
progressLabel.setText("00:00/" + finalDuration);
|
||||
progressSlider.setMaximum((int) durationMillis);
|
||||
progressSlider.setMinimum(0);
|
||||
final String finalDuration;
|
||||
if (duration.length() == 8 && duration.substring(0, 3).equals("00:")) {
|
||||
finalDuration = duration.substring(3);
|
||||
progressLabel.setText("00:00/" + duration);
|
||||
} else {
|
||||
progressLabel.setText("00:00:00/" + finalDuration);
|
||||
finalDuration = duration;
|
||||
progressLabel.setText("00:00:00/" + duration);
|
||||
}
|
||||
// If it reached the end
|
||||
if (progressSlider.getValue() == progressSlider.getMaximum()) {
|
||||
restartVideo();
|
||||
}
|
||||
}
|
||||
|
||||
public void restartVideo() {
|
||||
synchronized (playbinLock) {
|
||||
if (playbin2 != null) {
|
||||
playbin2.stop();
|
||||
playbin2.setState(State.READY); // ready to be played again
|
||||
}
|
||||
playbin2.play();
|
||||
}
|
||||
pauseButton.setText("►");
|
||||
progressSlider.setValue(0);
|
||||
pauseButton.setText("||");
|
||||
videoProgressWorker = new VideoProgressWorker();
|
||||
videoProgressWorker.execute();
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class VideoProgressWorker extends SwingWorker<Object, Object> {
|
||||
|
||||
private boolean isPlayBinReady() {
|
||||
synchronized (playbinLock) {
|
||||
return playbin2 != null && !playbin2.getState().equals(State.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
public void restartVideo() {
|
||||
synchronized (playbinLock) {
|
||||
if (playbin2 != null) {
|
||||
playbin2.stop();
|
||||
playbin2.setState(State.READY); // ready to be played again
|
||||
}
|
||||
}
|
||||
pauseButton.setText("►");
|
||||
progressSlider.setValue(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
long positionMillis = 0;
|
||||
String finalDuration = "";
|
||||
while (positionMillis < durationMillis
|
||||
&& isPlayBinReady() && !isCancelled()) {
|
||||
ClockTime pos = null;
|
||||
synchronized (playbinLock) {
|
||||
pos = playbin2.queryPosition();
|
||||
}
|
||||
String position = pos.toString();
|
||||
positionMillis = pos.toMillis();
|
||||
|
||||
if (position.length() == 8) {
|
||||
position = position.substring(3);
|
||||
}
|
||||
|
||||
String duration = playbin2.queryDuration().toString();
|
||||
if (duration.length() == 8 && duration.substring(0, 3).equals("00:")) {
|
||||
finalDuration = duration.substring(3);
|
||||
progressLabel.setText("00:00/" + duration);
|
||||
} else {
|
||||
finalDuration = duration;
|
||||
progressLabel.setText("00:00:00/" + duration);
|
||||
}
|
||||
|
||||
progressLabel.setText(position + "/" + finalDuration);
|
||||
autoTracking = true;
|
||||
progressSlider.setValue((int) positionMillis);
|
||||
autoTracking = false;
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (finalDuration.length() == 5) {
|
||||
progressLabel.setText("00:00/" + finalDuration);
|
||||
} else {
|
||||
progressLabel.setText("00:00:00/" + finalDuration);
|
||||
}
|
||||
// If it reached the end
|
||||
if (progressSlider.getValue() == progressSlider.getMaximum()) {
|
||||
restartVideo();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
<?xml version="1.1" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="picViewerScrollPanel" alignment="0" pref="589" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="picViewerScrollPanel" alignment="0" pref="382" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="picViewerScrollPanel">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="picLabel">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="0"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerPicture.picLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.corecomponents;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Image;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JPanel;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.File;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* File content viewer capable of displaying some image formats.
|
||||
*/
|
||||
//@ServiceProvider(service = DataContentViewer.class)
|
||||
public class DataContentViewerPicture extends javax.swing.JPanel implements DataContentViewer {
|
||||
|
||||
// for error handling
|
||||
private JPanel caller;
|
||||
private String className = this.getClass().toString();
|
||||
|
||||
/** Creates new form DataContentViewerPicture */
|
||||
public DataContentViewerPicture() {
|
||||
initComponents();
|
||||
this.resetComponent();
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
picViewerScrollPanel = new javax.swing.JScrollPane();
|
||||
picLabel = new javax.swing.JLabel();
|
||||
|
||||
picLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
picLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerPicture.class, "DataContentViewerPicture.picLabel.text")); // NOI18N
|
||||
picLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||
picViewerScrollPanel.setViewportView(picLabel);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(picViewerScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(picViewerScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel picLabel;
|
||||
private javax.swing.JScrollPane picViewerScrollPanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
public void setNode(Node selectedNode) {
|
||||
// change the cursor to "waiting cursor" for this operation
|
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
try {
|
||||
if (selectedNode != null) {
|
||||
try {
|
||||
// read the byte of the image file
|
||||
|
||||
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||
byte[] dataSource = new byte[(int) content.getSize()];
|
||||
int bytesRead = content.read(dataSource, 0, content.getSize());
|
||||
|
||||
// create the input stream for the content
|
||||
if (bytesRead > 0) {
|
||||
InputStream is = new ByteArrayInputStream(dataSource);
|
||||
|
||||
Image image = ImageIO.read(is); // create the image
|
||||
|
||||
if (image!= null)
|
||||
this.picLabel.setIcon(new javax.swing.ImageIcon(image)); // show the file
|
||||
}
|
||||
|
||||
|
||||
} catch (TskException ex) {
|
||||
// TODO: maybe make errors bubble
|
||||
Logger.getLogger(this.className).log(Level.WARNING, "Error while trying to display the picture content.", ex);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(this.className).log(Level.WARNING, "Error while trying to display the picture content.", ex);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.setCursor(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Picture View";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTip() {
|
||||
return "Displays supported image files.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataContentViewer getInstance() {
|
||||
return new DataContentViewerPicture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetComponent() {
|
||||
this.picLabel.setText("");
|
||||
//this.picLabel.setIcon(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
if (node != null) {
|
||||
// Note: only supports JPG, GIF, and PNG for now
|
||||
/*return node.getDisplayName().toLowerCase().endsWith(".jpg")
|
||||
|| node.getDisplayName().toLowerCase().endsWith(".jpeg")
|
||||
|| node.getDisplayName().toLowerCase().endsWith(".jpe")
|
||||
|| node.getDisplayName().toLowerCase().endsWith(".jfif")
|
||||
|| node.getDisplayName().toLowerCase().endsWith(".gif")
|
||||
|| node.getDisplayName().toLowerCase().endsWith(".bmp")
|
||||
|| //node.getDisplayName().toLowerCase().endsWith(".tif") ||
|
||||
//node.getDisplayName().toLowerCase().endsWith(".tiff") ||
|
||||
//node.getDisplayName().toLowerCase().endsWith(".tga") ||
|
||||
node.getDisplayName().toLowerCase().endsWith(".png");*/
|
||||
File file = node.getLookup().lookup(File.class);
|
||||
|
||||
if (file != null) {
|
||||
return file.getSize() > 0
|
||||
&& (file.getName().toLowerCase().endsWith(".jpg")
|
||||
|| file.getName().toLowerCase().endsWith(".jpeg")
|
||||
|| file.getName().toLowerCase().endsWith(".jpe")
|
||||
|| file.getName().toLowerCase().endsWith(".jfif")
|
||||
|| file.getName().toLowerCase().endsWith(".gif")
|
||||
|| file.getName().toLowerCase().endsWith(".bmp")
|
||||
|| //node.getName().toLowerCase().endsWith(".tif") ||
|
||||
//node.getName().toLowerCase().endsWith(".tiff") ||
|
||||
//node.getName().toLowerCase().endsWith(".tga") ||
|
||||
file.getName().toLowerCase().endsWith(".png"));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isPreferred(Node node, boolean isSupported) {
|
||||
if(isSupported) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
}
|
@ -482,7 +482,7 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
|
||||
@Override
|
||||
public int isPreferred(Node node, boolean isSupported) {
|
||||
if(node != null && isSupported){
|
||||
return 2;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user