mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge https://github.com/jawallace/autopsy into finalize64installer
This commit is contained in:
commit
c754648924
@ -18,11 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.core;
|
package org.sleuthkit.autopsy.core;
|
||||||
|
|
||||||
import com.sun.javafx.application.PlatformImpl;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.embed.swing.JFXPanel;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.openide.modules.ModuleInstall;
|
import org.openide.modules.ModuleInstall;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
@ -37,10 +37,11 @@ public class Installer extends ModuleInstall {
|
|||||||
|
|
||||||
private List<ModuleInstall> packageInstallers;
|
private List<ModuleInstall> packageInstallers;
|
||||||
private static final Logger logger = Logger.getLogger(Installer.class.getName());
|
private static final Logger logger = Logger.getLogger(Installer.class.getName());
|
||||||
private volatile boolean javaFxInit = true;
|
private static volatile boolean javaFxInit = false;
|
||||||
|
|
||||||
public Installer() {
|
public Installer() {
|
||||||
javaFxInit = true;
|
logger.log(Level.INFO, "core installer created");
|
||||||
|
javaFxInit = false;
|
||||||
packageInstallers = new ArrayList<ModuleInstall>();
|
packageInstallers = new ArrayList<ModuleInstall>();
|
||||||
|
|
||||||
packageInstallers.add(org.sleuthkit.autopsy.coreutils.Installer.getDefault());
|
packageInstallers.add(org.sleuthkit.autopsy.coreutils.Installer.getDefault());
|
||||||
@ -54,23 +55,20 @@ public class Installer extends ModuleInstall {
|
|||||||
* Check if JavaFx initialized
|
* Check if JavaFx initialized
|
||||||
* @return false if java fx not initialized (classes coult not load), true if initialized
|
* @return false if java fx not initialized (classes coult not load), true if initialized
|
||||||
*/
|
*/
|
||||||
public boolean isJavaFxInited() {
|
public static boolean isJavaFxInited() {
|
||||||
return this.javaFxInit;
|
return javaFxInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initJavaFx() {
|
private static void initJavaFx() {
|
||||||
//initialize java fx if exists
|
//initialize java fx if exists
|
||||||
|
System.setProperty("javafx.macosx.embedded", "true");
|
||||||
try {
|
try {
|
||||||
|
// Creating a JFXPanel initializes JavaFX
|
||||||
|
new JFXPanel();
|
||||||
Platform.setImplicitExit(false);
|
Platform.setImplicitExit(false);
|
||||||
PlatformImpl.startup(new Runnable() {
|
javaFxInit = true;
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
logger.log(Level.INFO, "Initializing JavaFX for image viewing");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (UnsatisfiedLinkError | NoClassDefFoundError | Exception e) {
|
} catch (UnsatisfiedLinkError | NoClassDefFoundError | Exception e) {
|
||||||
//in case javafx not present
|
//in case javafx not present
|
||||||
javaFxInit = false;
|
|
||||||
final String msg = "Error initializing JavaFX. ";
|
final String msg = "Error initializing JavaFX. ";
|
||||||
final String details = " Some features will not be available. "
|
final String details = " Some features will not be available. "
|
||||||
+ " Check that you have the right JRE installed (Oracle JRE > 1.7.10). ";
|
+ " Check that you have the right JRE installed (Oracle JRE > 1.7.10). ";
|
||||||
|
@ -361,6 +361,7 @@
|
|||||||
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-ingest-IngestMessagesAction.instance"/>
|
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-ingest-IngestMessagesAction.instance"/>
|
||||||
</file>
|
</file>
|
||||||
</folder>
|
</folder>
|
||||||
|
<folder name="QuickSearch_hidden" />
|
||||||
</folder>
|
</folder>
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.corecomponentinterfaces;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
@ -71,17 +72,47 @@ public class CoreComponentControl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes all TopComponent windows that needed ({@link DataExplorer}, {@link DataResult}, and
|
* Closes all TopComponent windows that needed ({@link DataExplorer}, {@link DataResult}, and
|
||||||
* {@link DataContent})
|
* {@link DataContent}).
|
||||||
|
*
|
||||||
|
* Note: The DataContent Top Component must be closed before the Directory Tree
|
||||||
|
* and Favorites Top Components. Otherwise a NullPointerException will be thrown
|
||||||
|
* from JFXPanel.
|
||||||
*/
|
*/
|
||||||
public static void closeCoreWindows() {
|
public static void closeCoreWindows() {
|
||||||
WindowManager wm = WindowManager.getDefault();
|
WindowManager wm = WindowManager.getDefault();
|
||||||
|
Set<? extends Mode> modes = wm.getModes();
|
||||||
Iterator<? extends Mode> iter = wm.getModes().iterator();
|
Iterator<? extends Mode> iter = wm.getModes().iterator();
|
||||||
|
|
||||||
|
TopComponent directoryTree = null;
|
||||||
|
TopComponent favorites = null;
|
||||||
|
String tcName = "";
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Mode mode = iter.next();
|
Mode mode = iter.next();
|
||||||
for (TopComponent tc : mode.getTopComponents()) {
|
for (TopComponent tc : mode.getTopComponents()) {
|
||||||
tc.close();
|
tcName = tc.getName();
|
||||||
|
if (tcName == null) {
|
||||||
|
logger.log(Level.INFO, "tcName was null");
|
||||||
|
tcName = "";
|
||||||
}
|
}
|
||||||
|
switch (tcName) {
|
||||||
|
case "Directory Tree":
|
||||||
|
directoryTree = tc;
|
||||||
|
break;
|
||||||
|
case "Favorites":
|
||||||
|
favorites = tc;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tc.close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directoryTree != null) {
|
||||||
|
directoryTree.close();
|
||||||
|
}
|
||||||
|
if (favorites != null) {
|
||||||
|
favorites.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,8 +189,7 @@ public class DataContentPanel extends javax.swing.JPanel implements DataContent,
|
|||||||
// let the user decide if we should stay with the current viewer
|
// let the user decide if we should stay with the current viewer
|
||||||
int tabIndex = keepCurrentViewer ? currTabIndex : preferredViewerIndex;
|
int tabIndex = keepCurrentViewer ? currTabIndex : preferredViewerIndex;
|
||||||
|
|
||||||
// set the tab to the one the user wants, then set that viewer's node.
|
|
||||||
jTabbedPane1.setSelectedIndex(tabIndex);
|
|
||||||
UpdateWrapper dcv = viewers.get(tabIndex);
|
UpdateWrapper dcv = viewers.get(tabIndex);
|
||||||
// this is really only needed if no tabs were enabled
|
// this is really only needed if no tabs were enabled
|
||||||
if (jTabbedPane1.isEnabledAt(tabIndex) == false) {
|
if (jTabbedPane1.isEnabledAt(tabIndex) == false) {
|
||||||
@ -199,6 +198,9 @@ public class DataContentPanel extends javax.swing.JPanel implements DataContent,
|
|||||||
else {
|
else {
|
||||||
dcv.setNode(selectedNode);
|
dcv.setNode(selectedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the tab to the one the user wants, then set that viewer's node.
|
||||||
|
jTabbedPane1.setSelectedIndex(tabIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -128,7 +128,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
|||||||
return; //prevent from loading twice if setNode() called mult. times
|
return; //prevent from loading twice if setNode() called mult. times
|
||||||
}
|
}
|
||||||
|
|
||||||
resetComponent();
|
lastFile = file;
|
||||||
|
|
||||||
final Dimension dims = DataContentViewerMedia.this.getSize();
|
final Dimension dims = DataContentViewerMedia.this.getSize();
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
|||||||
videoPanel.setupVideo(file, dims);
|
videoPanel.setupVideo(file, dims);
|
||||||
switchPanels(true);
|
switchPanels(true);
|
||||||
}
|
}
|
||||||
lastFile = file;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "Exception while setting node", e);
|
logger.log(Level.SEVERE, "Exception while setting node", e);
|
||||||
}
|
}
|
||||||
@ -182,8 +182,8 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetComponent() {
|
public void resetComponent() {
|
||||||
videoPanel.reset();
|
// No need to reset the video panel. It resets itself when a node is
|
||||||
// @@@ Seems like we should also reset the image viewer...
|
// set.
|
||||||
lastFile = null;
|
lastFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.4" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="0" green="0" red="0" type="rgb"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<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="true"/>
|
||||||
|
<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"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||||
|
</Form>
|
@ -18,14 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
import com.sun.javafx.application.PlatformImpl;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
@ -45,19 +44,23 @@ import javafx.scene.layout.HBox;
|
|||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.media.Media;
|
import javafx.scene.media.Media;
|
||||||
|
import javafx.scene.media.MediaBuilder;
|
||||||
import javafx.scene.media.MediaException;
|
import javafx.scene.media.MediaException;
|
||||||
import javafx.scene.media.MediaPlayer;
|
import javafx.scene.media.MediaPlayer;
|
||||||
import javafx.scene.media.MediaPlayer.Status;
|
import javafx.scene.media.MediaPlayer.Status;
|
||||||
|
import static javafx.scene.media.MediaPlayer.Status.PAUSED;
|
||||||
|
import static javafx.scene.media.MediaPlayer.Status.PLAYING;
|
||||||
import static javafx.scene.media.MediaPlayer.Status.READY;
|
import static javafx.scene.media.MediaPlayer.Status.READY;
|
||||||
|
import static javafx.scene.media.MediaPlayer.Status.STOPPED;
|
||||||
|
import javafx.scene.media.MediaPlayerBuilder;
|
||||||
import javafx.scene.media.MediaView;
|
import javafx.scene.media.MediaView;
|
||||||
|
import javafx.scene.text.Font;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
import org.openide.modules.ModuleInstall;
|
|
||||||
import org.openide.util.Cancellable;
|
import org.openide.util.Cancellable;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.openide.util.lookup.ServiceProviders;
|
import org.openide.util.lookup.ServiceProviders;
|
||||||
@ -67,6 +70,7 @@ import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
|||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
import org.sleuthkit.autopsy.core.Installer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Video viewer part of the Media View layered pane.
|
* Video viewer part of the Media View layered pane.
|
||||||
@ -79,7 +83,6 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
private static final Logger logger = Logger.getLogger(MediaViewVideoPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(MediaViewVideoPanel.class.getName());
|
||||||
private boolean fxInited = false;
|
private boolean fxInited = false;
|
||||||
// FX Components
|
// FX Components
|
||||||
private MediaPlayer fxMediaPlayer;
|
|
||||||
private MediaPane mediaPane;
|
private MediaPane mediaPane;
|
||||||
// Current media content representations
|
// Current media content representations
|
||||||
private AbstractFile currentFile;
|
private AbstractFile currentFile;
|
||||||
@ -90,35 +93,53 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
* Creates new form MediaViewVideoPanel
|
* Creates new form MediaViewVideoPanel
|
||||||
*/
|
*/
|
||||||
public FXVideoPanel() {
|
public FXVideoPanel() {
|
||||||
org.sleuthkit.autopsy.core.Installer coreInstaller =
|
fxInited = Installer.isJavaFxInited();
|
||||||
ModuleInstall.findObject(org.sleuthkit.autopsy.core.Installer.class, false);
|
|
||||||
if (coreInstaller != null) {
|
|
||||||
fxInited = coreInstaller.isJavaFxInited();
|
|
||||||
}
|
|
||||||
initComponents();
|
initComponents();
|
||||||
customizeComponents();
|
if (fxInited) {
|
||||||
|
setupFx();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPanel getVideoPanel() {
|
public JPanel getVideoPanel() {
|
||||||
return videoPanel;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getVideoComponent() {
|
private void setupFx() {
|
||||||
return videoComponent;
|
Platform.runLater(new Runnable() {
|
||||||
}
|
@Override
|
||||||
|
public void run() {
|
||||||
|
videoComponent = new JFXPanel();
|
||||||
|
mediaPane = new MediaPane();
|
||||||
|
Scene fxScene = new Scene(mediaPane);
|
||||||
|
videoComponent.setScene(fxScene);
|
||||||
|
|
||||||
private void customizeComponents() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
setupFx();
|
@Override
|
||||||
|
public void run() {
|
||||||
|
add(videoComponent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized void setupVideo(final AbstractFile file, final Dimension dims) {
|
void setupVideo(final AbstractFile file, final Dimension dims) {
|
||||||
|
if(file.equals(currentFile)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Case.isCaseOpen()) {
|
||||||
|
//handle in-between condition when case is being closed
|
||||||
|
//and an image was previously selected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reset();
|
||||||
currentFile = file;
|
currentFile = file;
|
||||||
final boolean deleted = file.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC);
|
final boolean deleted = file.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC);
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
mediaPane.setInfoLabelText("Playback of deleted videos is not supported, use an external player.");
|
mediaPane.setInfoLabelText("Playback of deleted videos is not supported, use an external player.");
|
||||||
videoPanel.removeAll();
|
removeAll();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,56 +154,22 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
|
|
||||||
ExtractMedia em = new ExtractMedia(currentFile, getJFile(currentFile));
|
ExtractMedia em = new ExtractMedia(currentFile, getJFile(currentFile));
|
||||||
em.execute();
|
em.execute();
|
||||||
|
|
||||||
|
mediaPane.setFit(dims);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setupFx() {
|
|
||||||
if(!fxInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
logger.log(Level.INFO, "In Setup FX");
|
|
||||||
PlatformImpl.runLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mediaPane = new MediaPane();
|
|
||||||
logger.log(Level.INFO, "Created MediaPane");
|
|
||||||
Scene fxScene = new Scene(mediaPane);
|
|
||||||
videoComponent = new JFXPanel();
|
|
||||||
videoComponent.setScene(fxScene);
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Configure VideoPanel
|
|
||||||
videoPanel.removeAll();
|
|
||||||
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
|
|
||||||
videoPanel.add(videoComponent);
|
|
||||||
videoPanel.setVisible(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void reset() {
|
void reset() {
|
||||||
|
Platform.runLater(new Runnable() {
|
||||||
PlatformImpl.runLater(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (fxMediaPlayer != null) {
|
if (mediaPane != null) {
|
||||||
if (fxMediaPlayer.getStatus() == MediaPlayer.Status.PLAYING ) {
|
mediaPane.reset();
|
||||||
fxMediaPlayer.stop();
|
|
||||||
}
|
|
||||||
fxMediaPlayer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (videoComponent != null) {
|
|
||||||
videoComponent = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
currentFile = null;
|
currentFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,37 +194,14 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
* regenerated by the Form Editor.
|
* regenerated by the Form Editor.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
videoPanel = new javax.swing.JPanel();
|
setBackground(new java.awt.Color(0, 0, 0));
|
||||||
|
setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS));
|
||||||
javax.swing.GroupLayout videoPanelLayout = new javax.swing.GroupLayout(videoPanel);
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
videoPanel.setLayout(videoPanelLayout);
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
videoPanelLayout.setHorizontalGroup(
|
// End of variables declaration//GEN-END:variables
|
||||||
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 448, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
videoPanelLayout.setVerticalGroup(
|
|
||||||
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 248, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
|
||||||
this.setLayout(layout);
|
|
||||||
layout.setHorizontalGroup(
|
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(videoPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
layout.setVerticalGroup(
|
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
}// </editor-fold>
|
|
||||||
|
|
||||||
// Variables declaration - do not modify
|
|
||||||
private javax.swing.JPanel videoPanel;
|
|
||||||
// End of variables declaration
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInited() {
|
public boolean isInited() {
|
||||||
@ -265,8 +229,13 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
return extractedBytes;
|
return extractedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Media getMedia() {
|
/**
|
||||||
return new Media(Paths.get(jFile.getAbsolutePath()).toUri().toString());
|
* Get the URI of the media file.
|
||||||
|
*
|
||||||
|
* @return the URI of the media file.
|
||||||
|
*/
|
||||||
|
public String getMediaUri() {
|
||||||
|
return Paths.get(jFile.getAbsolutePath()).toUri().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -307,13 +276,10 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
if (!this.isCancelled()) {
|
if (!this.isCancelled()) {
|
||||||
logger.log(Level.INFO, "ExtractMedia in done: " + jFile.getName());
|
logger.log(Level.INFO, "ExtractMedia in done: " + jFile.getName());
|
||||||
try {
|
try {
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fxMediaPlayer = new MediaPlayer(getMedia());
|
mediaPane.prepareMedia(getMediaUri());
|
||||||
logger.log(Level.INFO, "Fx Media Player null? " + (fxMediaPlayer == null));
|
|
||||||
logger.log(Level.INFO, "Media Tools null? " + (mediaPane == null));
|
|
||||||
mediaPane.setMediaPlayer(fxMediaPlayer);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch(MediaException e) {
|
} catch(MediaException e) {
|
||||||
@ -327,14 +293,27 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JavaFX Component that contains the Media and it's Controls.
|
||||||
|
*
|
||||||
|
*/
|
||||||
private class MediaPane extends BorderPane {
|
private class MediaPane extends BorderPane {
|
||||||
private MediaPlayer mediaPlayer;
|
private MediaPlayer mediaPlayer;
|
||||||
private MediaView mediaView;
|
private MediaView mediaView;
|
||||||
|
/** The Duration of the media. **/
|
||||||
private Duration duration;
|
private Duration duration;
|
||||||
|
|
||||||
|
/** The container for the media controls. **/
|
||||||
private HBox mediaTools;
|
private HBox mediaTools;
|
||||||
|
|
||||||
|
/** The container for the media video output. **/
|
||||||
private HBox mediaViewPane;
|
private HBox mediaViewPane;
|
||||||
|
|
||||||
|
private VBox controlPanel;
|
||||||
|
|
||||||
private Slider progressSlider;
|
private Slider progressSlider;
|
||||||
private Button pauseButton;
|
private Button pauseButton;
|
||||||
|
private Button stopButton;
|
||||||
private Label progressLabel;
|
private Label progressLabel;
|
||||||
private Label infoLabel;
|
private Label infoLabel;
|
||||||
private int totalHours;
|
private int totalHours;
|
||||||
@ -342,6 +321,36 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
private int totalSeconds;
|
private int totalSeconds;
|
||||||
private String durationFormat = "%02d:%02d:%02d/%02d:%02d:%02d ";
|
private String durationFormat = "%02d:%02d:%02d/%02d:%02d:%02d ";
|
||||||
|
|
||||||
|
/** The EventHandler for MediaPlayer.onReady(). **/
|
||||||
|
private final ReadyListener READY_LISTENER = new ReadyListener();
|
||||||
|
|
||||||
|
/** The EventHandler for MediaPlayer.onEndOfMedia(). **/
|
||||||
|
private final EndOfMediaListener END_LISTENER = new EndOfMediaListener();
|
||||||
|
|
||||||
|
/** The EventHandler for the CurrentTime property of the MediaPlayer. **/
|
||||||
|
private final TimeListener TIME_LISTENER = new TimeListener();
|
||||||
|
|
||||||
|
/** The EventHandler for MediaPlayer.onPause and MediaPlayer.onStop. **/
|
||||||
|
private final NotPlayListener NOT_PLAY_LISTENER = new NotPlayListener();
|
||||||
|
|
||||||
|
/** The EventHandler for MediaPlayer.onPlay. **/
|
||||||
|
private final PlayListener PLAY_LISTENER = new PlayListener();
|
||||||
|
|
||||||
|
private static final String PLAY_TEXT = "►";
|
||||||
|
|
||||||
|
private static final String PAUSE_TEXT = "||";
|
||||||
|
|
||||||
|
private static final String STOP_TEXT = "X";
|
||||||
|
|
||||||
|
/** CSS-formatted skin for pauseButton when showing PLAY_TEXT. **/
|
||||||
|
private static final String PLAY_STYLE = "-fx-text-fill: green;";
|
||||||
|
|
||||||
|
/** CSS-formatted skin for pauseButton when showing PAUSE_TEXT. **/
|
||||||
|
private static final String PAUSE_STYLE = "-fx-font-weight: bolder;";
|
||||||
|
|
||||||
|
/** CSS-formatted skin for stopButton. **/
|
||||||
|
private static final String STOP_STYLE = "-fx-text-fill: red; -fx-font-weight: bold;";
|
||||||
|
|
||||||
public MediaPane() {
|
public MediaPane() {
|
||||||
// Video Display
|
// Video Display
|
||||||
mediaViewPane = new HBox();
|
mediaViewPane = new HBox();
|
||||||
@ -349,26 +358,30 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
mediaViewPane.setAlignment(Pos.CENTER);
|
mediaViewPane.setAlignment(Pos.CENTER);
|
||||||
mediaView = new MediaView();
|
mediaView = new MediaView();
|
||||||
mediaViewPane.getChildren().add(mediaView);
|
mediaViewPane.getChildren().add(mediaView);
|
||||||
setAlignment(mediaViewPane, Pos.CENTER);
|
|
||||||
setCenter(mediaViewPane);
|
setCenter(mediaViewPane);
|
||||||
|
|
||||||
// Media Controls
|
// Media Controls
|
||||||
VBox controlPanel = new VBox();
|
controlPanel = new VBox();
|
||||||
mediaTools = new HBox();
|
mediaTools = new HBox();
|
||||||
mediaTools.setAlignment(Pos.CENTER);
|
mediaTools.setAlignment(Pos.CENTER);
|
||||||
mediaTools.setPadding(new Insets(5, 10, 5, 10));
|
mediaTools.setPadding(new Insets(5, 10, 5, 10));
|
||||||
|
|
||||||
pauseButton = new Button("►");
|
pauseButton = new Button(PLAY_TEXT);
|
||||||
|
pauseButton.setStyle(PLAY_STYLE);
|
||||||
|
stopButton = new Button(STOP_TEXT);
|
||||||
|
stopButton.setStyle(STOP_STYLE);
|
||||||
mediaTools.getChildren().add(pauseButton);
|
mediaTools.getChildren().add(pauseButton);
|
||||||
mediaTools.getChildren().add(new Label(" "));
|
mediaTools.getChildren().add(new Label(" "));
|
||||||
|
mediaTools.getChildren().add(stopButton);
|
||||||
|
mediaTools.getChildren().add(new Label(" "));
|
||||||
progressSlider = new Slider();
|
progressSlider = new Slider();
|
||||||
HBox.setHgrow(progressSlider,Priority.ALWAYS);
|
HBox.setHgrow(progressSlider,Priority.ALWAYS);
|
||||||
progressSlider.setMinWidth(50);
|
progressSlider.setMinWidth(50);
|
||||||
progressSlider.setMaxWidth(Double.MAX_VALUE);
|
progressSlider.setMaxWidth(Double.MAX_VALUE);
|
||||||
mediaTools.getChildren().add(progressSlider);
|
mediaTools.getChildren().add(progressSlider);
|
||||||
progressLabel = new Label();
|
progressLabel = new Label();
|
||||||
progressLabel.setPrefWidth(130);
|
progressLabel.setPrefWidth(135);
|
||||||
progressLabel.setMinWidth(50);
|
progressLabel.setMinWidth(135);
|
||||||
mediaTools.getChildren().add(progressLabel);
|
mediaTools.getChildren().add(progressLabel);
|
||||||
|
|
||||||
controlPanel.getChildren().add(mediaTools);
|
controlPanel.getChildren().add(mediaTools);
|
||||||
@ -379,8 +392,39 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
setProgressActionListeners();
|
setProgressActionListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the MediaPane for media playback. Run on the JavaFx Thread.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param mediaUri the URI of the media
|
||||||
|
*/
|
||||||
|
public void prepareMedia(String mediaUri) {
|
||||||
|
mediaPlayer = createMediaPlayer(mediaUri);
|
||||||
|
mediaView.setMediaPlayer(mediaPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this MediaPane.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
if (mediaPlayer != null) {
|
||||||
|
if (mediaPlayer.getStatus() == Status.PLAYING) {
|
||||||
|
mediaPlayer.stop();
|
||||||
|
}
|
||||||
|
mediaPlayer = null;
|
||||||
|
}
|
||||||
|
resetProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Information Label of this MediaPane.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
public void setInfoLabelText(final String text) {
|
public void setInfoLabelText(final String text) {
|
||||||
PlatformImpl.runLater(new Runnable() {
|
logger.log(Level.INFO, "Setting Info Label Text: " + text);
|
||||||
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
infoLabel.setText(text);
|
infoLabel.setText(text);
|
||||||
@ -388,54 +432,26 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMediaPlayer(MediaPlayer mp) {
|
/**
|
||||||
pauseButton.setDisable(true);
|
* Set the size of the MediaPane and it's components.
|
||||||
mediaPlayer = mp;
|
*
|
||||||
mediaView.setMediaPlayer(mp);
|
* @param dims the current dimensions of the DataContentViewer
|
||||||
pauseButton.setDisable(false);
|
*/
|
||||||
|
public void setFit(final Dimension dims) {
|
||||||
setMediaActionListeners();
|
Platform.runLater(new Runnable() {
|
||||||
}
|
|
||||||
|
|
||||||
private void setMediaActionListeners() {
|
|
||||||
mediaPlayer.setOnReady(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
duration = mediaPlayer.getMedia().getDuration();
|
setPrefSize(dims.getWidth(), dims.getHeight());
|
||||||
long durationInMillis = (long) fxMediaPlayer.getMedia().getDuration().toMillis();
|
// Set the Video output to fit the size allocated for it. give an
|
||||||
|
// extra few px to ensure the info label will be shown
|
||||||
// pick out the total hours, minutes, seconds
|
mediaView.setFitHeight(dims.getHeight() - controlPanel.getHeight());
|
||||||
long durationSeconds = (int) durationInMillis / 1000;
|
|
||||||
totalHours = (int) durationSeconds / 3600;
|
|
||||||
durationSeconds -= totalHours * 3600;
|
|
||||||
totalMinutes = (int) durationSeconds / 60;
|
|
||||||
durationSeconds -= totalMinutes * 60;
|
|
||||||
totalSeconds = (int) durationSeconds;
|
|
||||||
updateProgress();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mediaPlayer.setOnEndOfMedia(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Duration beginning = mediaPlayer.getStartTime();
|
|
||||||
mediaPlayer.stop();
|
|
||||||
mediaPlayer.pause();
|
|
||||||
pauseButton.setText("►");
|
|
||||||
updateSlider(beginning);
|
|
||||||
updateTime(beginning);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
|
|
||||||
@Override
|
|
||||||
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
|
|
||||||
updateSlider(newValue);
|
|
||||||
updateTime(newValue);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the action listeners for the pause button and progress slider.
|
||||||
|
*/
|
||||||
private void setProgressActionListeners() {
|
private void setProgressActionListeners() {
|
||||||
pauseButton.setOnAction(new EventHandler<ActionEvent>() {
|
pauseButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
@Override
|
@Override
|
||||||
@ -445,22 +461,31 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
// If playing, pause
|
// If playing, pause
|
||||||
case PLAYING:
|
case PLAYING:
|
||||||
pauseButton.setText("►");
|
|
||||||
mediaPlayer.pause();
|
mediaPlayer.pause();
|
||||||
break;
|
break;
|
||||||
// If ready, paused or stopped, continue playing
|
// If ready, paused or stopped, continue playing
|
||||||
case READY:
|
case READY:
|
||||||
case PAUSED:
|
case PAUSED:
|
||||||
case STOPPED:
|
case STOPPED:
|
||||||
pauseButton.setText("||");
|
|
||||||
mediaPlayer.play();
|
mediaPlayer.play();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
logger.log(Level.INFO, "MediaPlayer in unexpected state: " + status.toString());
|
||||||
|
// If the MediaPlayer is in an unexpected state, stop playback.
|
||||||
|
mediaPlayer.stop();
|
||||||
|
setInfoLabelText("Playback error.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
stopButton.setOnAction(new EventHandler<ActionEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent e) {
|
||||||
|
mediaPlayer.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
progressSlider.valueProperty().addListener(new InvalidationListener() {
|
progressSlider.valueProperty().addListener(new InvalidationListener() {
|
||||||
@Override
|
@Override
|
||||||
public void invalidated(Observable o) {
|
public void invalidated(Observable o) {
|
||||||
@ -471,15 +496,61 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the progress label and slider to zero.
|
||||||
|
*/
|
||||||
|
private void resetProgress() {
|
||||||
|
totalHours = 0;
|
||||||
|
totalMinutes = 0;
|
||||||
|
totalSeconds = 0;
|
||||||
|
progressSlider.setValue(0.0);
|
||||||
|
updateTime(Duration.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a MediaPlayer from the given Media URI.
|
||||||
|
*
|
||||||
|
* Also adds the necessary listeners to MediaPlayer events.
|
||||||
|
*
|
||||||
|
* @param mediaUri the location of the media.
|
||||||
|
* @return a MediaPlayer
|
||||||
|
*/
|
||||||
|
private MediaPlayer createMediaPlayer(String mediaUri) {
|
||||||
|
MediaBuilder mediaBuilder = MediaBuilder.create();
|
||||||
|
mediaBuilder.source(mediaUri);
|
||||||
|
Media media = mediaBuilder.build();
|
||||||
|
|
||||||
|
MediaPlayerBuilder mediaPlayerBuilder = MediaPlayerBuilder.create();
|
||||||
|
mediaPlayerBuilder.media(media);
|
||||||
|
mediaPlayerBuilder.onReady(READY_LISTENER);
|
||||||
|
mediaPlayerBuilder.onPaused(NOT_PLAY_LISTENER);
|
||||||
|
mediaPlayerBuilder.onStopped(NOT_PLAY_LISTENER);
|
||||||
|
mediaPlayerBuilder.onPlaying(PLAY_LISTENER);
|
||||||
|
mediaPlayerBuilder.onEndOfMedia(END_LISTENER);
|
||||||
|
|
||||||
|
MediaPlayer player = mediaPlayerBuilder.build();
|
||||||
|
player.currentTimeProperty().addListener(TIME_LISTENER);
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the progress slider and label with the current time of the media.
|
||||||
|
*/
|
||||||
private void updateProgress() {
|
private void updateProgress() {
|
||||||
Duration currentTime = mediaPlayer.getCurrentTime();
|
Duration currentTime = mediaPlayer.getCurrentTime();
|
||||||
updateSlider(currentTime);
|
updateSlider(currentTime);
|
||||||
updateTime(currentTime);
|
updateTime(currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the slider with the current time.
|
||||||
|
*
|
||||||
|
* @param currentTime
|
||||||
|
*/
|
||||||
private void updateSlider(Duration currentTime) {
|
private void updateSlider(Duration currentTime) {
|
||||||
if (progressSlider != null) {
|
if (progressSlider != null) {
|
||||||
progressSlider.setDisable(duration.isUnknown());
|
progressSlider.setDisable(currentTime.isUnknown());
|
||||||
if (!progressSlider.isDisabled() && duration.greaterThan(Duration.ZERO)
|
if (!progressSlider.isDisabled() && duration.greaterThan(Duration.ZERO)
|
||||||
&& !progressSlider.isValueChanging()) {
|
&& !progressSlider.isValueChanging()) {
|
||||||
progressSlider.setValue(currentTime.divide(duration.toMillis()).toMillis() * 100.0);
|
progressSlider.setValue(currentTime.divide(duration.toMillis()).toMillis() * 100.0);
|
||||||
@ -487,6 +558,11 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the progress label with the current time.
|
||||||
|
*
|
||||||
|
* @param currentTime
|
||||||
|
*/
|
||||||
private void updateTime(Duration currentTime) {
|
private void updateTime(Duration currentTime) {
|
||||||
long millisElapsed = (long) currentTime.toMillis();
|
long millisElapsed = (long) currentTime.toMillis();
|
||||||
|
|
||||||
@ -502,11 +578,16 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
String durationStr = String.format(durationFormat,
|
String durationStr = String.format(durationFormat,
|
||||||
elapsedHours, elapsedMinutes, elapsedSeconds,
|
elapsedHours, elapsedMinutes, elapsedSeconds,
|
||||||
totalHours, totalMinutes, totalSeconds);
|
totalHours, totalMinutes, totalSeconds);
|
||||||
progressLabel.setText(durationStr);
|
setProgressLabelText(durationStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the progress label to show the text.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
private void setProgressLabelText(final String text) {
|
private void setProgressLabelText(final String text) {
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
progressLabel.setText(text);
|
progressLabel.setText(text);
|
||||||
@ -515,13 +596,87 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setInfoLabelToolTipText(final String text) {
|
private void setInfoLabelToolTipText(final String text) {
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
infoLabel.setTooltip(new Tooltip(text));
|
infoLabel.setTooltip(new Tooltip(text));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responds to MediaPlayer onReady events.
|
||||||
|
*
|
||||||
|
* Updates the progress label with the duration of the media.
|
||||||
|
*/
|
||||||
|
private class ReadyListener implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
duration = mediaPlayer.getMedia().getDuration();
|
||||||
|
long durationInMillis = (long) mediaPlayer.getMedia().getDuration().toMillis();
|
||||||
|
|
||||||
|
// pick out the total hours, minutes, seconds
|
||||||
|
long durationSeconds = (int) durationInMillis / 1000;
|
||||||
|
totalHours = (int) durationSeconds / 3600;
|
||||||
|
durationSeconds -= totalHours * 3600;
|
||||||
|
totalMinutes = (int) durationSeconds / 60;
|
||||||
|
durationSeconds -= totalMinutes * 60;
|
||||||
|
totalSeconds = (int) durationSeconds;
|
||||||
|
updateProgress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responds to MediaPlayer onEndOfMediaEvents.
|
||||||
|
*
|
||||||
|
* Prepares the media to be replayed.
|
||||||
|
*/
|
||||||
|
private class EndOfMediaListener implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Duration beginning = mediaPlayer.getStartTime();
|
||||||
|
mediaPlayer.stop();
|
||||||
|
mediaPlayer.pause();
|
||||||
|
pauseButton.setText(PLAY_TEXT);
|
||||||
|
updateSlider(beginning);
|
||||||
|
updateTime(beginning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responds to changes in the MediaPlayer currentTime property.
|
||||||
|
*
|
||||||
|
* Updates the progress slider and label with the current Time.
|
||||||
|
*/
|
||||||
|
private class TimeListener implements ChangeListener<Duration> {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
|
||||||
|
updateSlider(newValue);
|
||||||
|
updateTime(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when MediaPlayer State changes to PAUSED or Stopped.
|
||||||
|
*/
|
||||||
|
private class NotPlayListener implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
pauseButton.setText(PLAY_TEXT);
|
||||||
|
pauseButton.setStyle(PLAY_STYLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when MediaPlayer State changes to PLAYING.
|
||||||
|
*/
|
||||||
|
private class PlayListener implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
pauseButton.setText(PAUSE_TEXT);
|
||||||
|
pauseButton.setStyle(PAUSE_STYLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -566,7 +721,7 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// private void initFx(final java.io.File file) {
|
// private void initFx(final java.io.File file) {
|
||||||
// PlatformImpl.runAndWait(new Runnable() {
|
// Platform.runAndWait(new Runnable() {
|
||||||
// @Override
|
// @Override
|
||||||
// public void run() {
|
// public void run() {
|
||||||
// logger.log(Level.INFO, "In initFX.");
|
// logger.log(Level.INFO, "In initFX.");
|
||||||
@ -620,7 +775,7 @@ public class FXVideoPanel extends MediaViewVideoPanel {
|
|||||||
// logger.log(Level.INFO, "Grabbing a frame...");
|
// logger.log(Level.INFO, "Grabbing a frame...");
|
||||||
// final long timeStamp = i * frameInterval + INTER_FRAME_PERIOD_MS;
|
// final long timeStamp = i * frameInterval + INTER_FRAME_PERIOD_MS;
|
||||||
//
|
//
|
||||||
// // PlatformImpl.runLater(new Runnable() {
|
// // Platform.runLater(new Runnable() {
|
||||||
// // @Override
|
// // @Override
|
||||||
// // public void run() {
|
// // public void run() {
|
||||||
// // synchronized (frameLock) {
|
// // synchronized (frameLock) {
|
||||||
|
120
Core/src/org/sleuthkit/autopsy/corecomponents/GstVideoPanel.form
Normal file
120
Core/src/org/sleuthkit/autopsy/corecomponents/GstVideoPanel.form
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.8" 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="true"/>
|
||||||
|
<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="controlPanel" max="32767" attributes="0"/>
|
||||||
|
<Component id="videoPanel" alignment="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="videoPanel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="controlPanel" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="videoPanel">
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="231" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="controlPanel">
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<EmptySpace min="6" pref="6" max="-2" attributes="0"/>
|
||||||
|
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="pauseButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="progressSlider" pref="265" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="progressLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="progressSlider" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="pauseButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="progressLabel" alignment="0" min="-2" pref="29" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JButton" name="pauseButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MediaViewVideoPanel.pauseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pauseButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JSlider" name="progressSlider">
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="progressLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MediaViewVideoPanel.progressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="infoLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MediaViewVideoPanel.infoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -437,7 +437,7 @@ public class GstVideoPanel extends MediaViewVideoPanel {
|
|||||||
* regenerated by the Form Editor.
|
* regenerated by the Form Editor.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
videoPanel = new javax.swing.JPanel();
|
videoPanel = new javax.swing.JPanel();
|
||||||
@ -455,69 +455,70 @@ public class GstVideoPanel extends MediaViewVideoPanel {
|
|||||||
);
|
);
|
||||||
videoPanelLayout.setVerticalGroup(
|
videoPanelLayout.setVerticalGroup(
|
||||||
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 188, Short.MAX_VALUE)
|
.addGap(0, 231, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(pauseButton, org.openide.util.NbBundle.getMessage(MediaViewVideoPanel.class, "MediaViewVideoPanel.pauseButton.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(pauseButton, org.openide.util.NbBundle.getMessage(GstVideoPanel.class, "MediaViewVideoPanel.pauseButton.text")); // NOI18N
|
||||||
pauseButton.addActionListener(new java.awt.event.ActionListener() {
|
pauseButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
pauseButtonActionPerformed(evt);
|
pauseButtonActionPerformed(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(MediaViewVideoPanel.class, "MediaViewVideoPanel.progressLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(GstVideoPanel.class, "MediaViewVideoPanel.progressLabel.text")); // NOI18N
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(MediaViewVideoPanel.class, "MediaViewVideoPanel.infoLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(GstVideoPanel.class, "MediaViewVideoPanel.infoLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel);
|
javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel);
|
||||||
controlPanel.setLayout(controlPanelLayout);
|
controlPanel.setLayout(controlPanelLayout);
|
||||||
controlPanelLayout.setHorizontalGroup(
|
controlPanelLayout.setHorizontalGroup(
|
||||||
controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(controlPanelLayout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(controlPanelLayout.createSequentialGroup()
|
||||||
|
.addGap(6, 6, 6)
|
||||||
|
.addComponent(infoLabel)
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||||
.addGroup(controlPanelLayout.createSequentialGroup()
|
.addGroup(controlPanelLayout.createSequentialGroup()
|
||||||
.addComponent(pauseButton)
|
.addComponent(pauseButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
|
.addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(progressLabel)
|
.addComponent(progressLabel)
|
||||||
.addContainerGap())
|
.addContainerGap())))
|
||||||
.addGroup(controlPanelLayout.createSequentialGroup()
|
|
||||||
.addComponent(infoLabel)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE))
|
|
||||||
);
|
);
|
||||||
controlPanelLayout.setVerticalGroup(
|
controlPanelLayout.setVerticalGroup(
|
||||||
controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(controlPanelLayout.createSequentialGroup()
|
.addGroup(controlPanelLayout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
.addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(pauseButton)
|
|
||||||
.addComponent(progressSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(progressSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(progressLabel, javax.swing.GroupLayout.Alignment.TRAILING))
|
.addComponent(pauseButton)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addComponent(progressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addComponent(infoLabel))
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(infoLabel)
|
||||||
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(videoPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addContainerGap())
|
|
||||||
);
|
);
|
||||||
}// </editor-fold>
|
}// </editor-fold>
|
||||||
|
|
||||||
private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {
|
private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pauseButtonActionPerformed
|
||||||
synchronized (playbinLock) {
|
synchronized (playbinLock) {
|
||||||
if (gstPlaybin2 == null) {
|
|
||||||
infoLabel.setText("Error: Playbin is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
State state = gstPlaybin2.getState();
|
State state = gstPlaybin2.getState();
|
||||||
if (state.equals(State.PLAYING)) {
|
if (state.equals(State.PLAYING)) {
|
||||||
if (gstPlaybin2.pause() == StateChangeReturn.FAILURE) {
|
if (gstPlaybin2.pause() == StateChangeReturn.FAILURE) {
|
||||||
@ -551,15 +552,16 @@ public class GstVideoPanel extends MediaViewVideoPanel {
|
|||||||
em.getExtractedBytes();
|
em.getExtractedBytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}//GEN-LAST:event_pauseButtonActionPerformed
|
||||||
// Variables declaration - do not modify
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JPanel controlPanel;
|
private javax.swing.JPanel controlPanel;
|
||||||
private javax.swing.JLabel infoLabel;
|
private javax.swing.JLabel infoLabel;
|
||||||
private javax.swing.JButton pauseButton;
|
private javax.swing.JButton pauseButton;
|
||||||
private javax.swing.JLabel progressLabel;
|
private javax.swing.JLabel progressLabel;
|
||||||
private javax.swing.JSlider progressSlider;
|
private javax.swing.JSlider progressSlider;
|
||||||
private javax.swing.JPanel videoPanel;
|
private javax.swing.JPanel videoPanel;
|
||||||
// End of variables declaration
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
private class VideoProgressWorker extends SwingWorker<Object, Object> {
|
private class VideoProgressWorker extends SwingWorker<Object, Object> {
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
import com.sun.javafx.application.PlatformImpl;
|
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javafx.application.Platform;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
@ -29,9 +29,9 @@ import javax.swing.UIManager.LookAndFeelInfo;
|
|||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
|
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
|
||||||
import org.openide.modules.ModuleInstall;
|
import org.openide.modules.ModuleInstall;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages this module's lifecycle. Opens the startup dialog during startup.
|
* Manages this module's lifecycle. Opens the startup dialog during startup.
|
||||||
@ -57,7 +57,7 @@ public class Installer extends ModuleInstall {
|
|||||||
public void restored() {
|
public void restored() {
|
||||||
super.restored();
|
super.restored();
|
||||||
|
|
||||||
//setupLAF();
|
setupLAF();
|
||||||
UIManager.put("ViewTabDisplayerUI", "org.sleuthkit.autopsy.corecomponents.NoTabsTabDisplayerUI");
|
UIManager.put("ViewTabDisplayerUI", "org.sleuthkit.autopsy.corecomponents.NoTabsTabDisplayerUI");
|
||||||
UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder());
|
UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder());
|
||||||
UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));
|
UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));
|
||||||
@ -85,24 +85,57 @@ public class Installer extends ModuleInstall {
|
|||||||
//UIManager.put("nimbusBlueGrey", new Color());
|
//UIManager.put("nimbusBlueGrey", new Color());
|
||||||
//UIManager.put("control", new Color());
|
//UIManager.put("control", new Color());
|
||||||
|
|
||||||
|
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
|
||||||
|
setupMacOsXLAF();
|
||||||
|
}
|
||||||
|
|
||||||
Logger logger = Logger.getLogger(Installer.class.getName());
|
}
|
||||||
//use Nimbus if available
|
|
||||||
|
/**
|
||||||
|
* Set the look and feel to be the Cross Platform 'Metal', but keep Aqua
|
||||||
|
* dependent elements that set the Menu Bar to be in the correct place on
|
||||||
|
* Mac OS X.
|
||||||
|
*/
|
||||||
|
private void setupMacOsXLAF() {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (ClassNotFoundException | InstantiationException
|
||||||
|
| IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String[] UI_MENU_ITEM_KEYS = new String[]{"MenuBarUI",
|
||||||
|
"MenuUI",
|
||||||
|
"MenuItemUI",
|
||||||
|
"CheckBoxMenuItemUI",
|
||||||
|
"RadioButtonMenuItemUI",
|
||||||
|
"PopupMenuUI"};
|
||||||
|
|
||||||
|
Map<Object, Object> uiEntries = new TreeMap<Object, Object>();
|
||||||
|
|
||||||
|
// Store the keys that deal with menu items
|
||||||
|
for(String key : UI_MENU_ITEM_KEYS) {
|
||||||
|
uiEntries.put(key, UIManager.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//use Metal if available
|
||||||
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
|
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
|
||||||
if ("Nimbus".equals(info.getName())) {
|
if ("Nimbus".equals(info.getName())) {
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(info.getClassName());
|
UIManager.setLookAndFeel(info.getClassName());
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException | InstantiationException |
|
||||||
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||||
} catch (InstantiationException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
|
||||||
} catch (UnsupportedLookAndFeelException ex) {
|
|
||||||
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
logger.log(Level.WARNING, "Unable to set theme. ", ex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overwrite the Metal menu item keys to use the Aqua versions
|
||||||
|
for(Map.Entry entry : uiEntries.entrySet()) {
|
||||||
|
UIManager.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponents;
|
package org.sleuthkit.autopsy.corecomponents;
|
||||||
|
|
||||||
import com.sun.javafx.application.PlatformImpl;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.embed.swing.JFXPanel;
|
import javafx.embed.swing.JFXPanel;
|
||||||
import javafx.embed.swing.SwingFXUtils;
|
import javafx.embed.swing.SwingFXUtils;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
@ -33,8 +32,7 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import org.openide.modules.ModuleInstall;
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.util.Lookup;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.corelibs.ScalrWrapper;
|
import org.sleuthkit.autopsy.corelibs.ScalrWrapper;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -61,11 +59,7 @@ public class MediaViewImagePanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
org.sleuthkit.autopsy.core.Installer coreInstaller =
|
fxInited = org.sleuthkit.autopsy.core.Installer.isJavaFxInited();
|
||||||
ModuleInstall.findObject(org.sleuthkit.autopsy.core.Installer.class, false);
|
|
||||||
if (coreInstaller != null) {
|
|
||||||
fxInited = coreInstaller.isJavaFxInited();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (fxInited) {
|
if (fxInited) {
|
||||||
@ -82,7 +76,7 @@ public class MediaViewImagePanel extends javax.swing.JPanel {
|
|||||||
*/
|
*/
|
||||||
private void setupFx() {
|
private void setupFx() {
|
||||||
// load the image
|
// load the image
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fxPanel = new JFXPanel();
|
fxPanel = new JFXPanel();
|
||||||
@ -129,7 +123,7 @@ public class MediaViewImagePanel extends javax.swing.JPanel {
|
|||||||
fxPanel.setVisible(false);
|
fxPanel.setVisible(false);
|
||||||
|
|
||||||
// load the image
|
// load the image
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!Case.isCaseOpen()) {
|
if (!Case.isCaseOpen()) {
|
||||||
@ -188,8 +182,13 @@ public class MediaViewImagePanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
fxPanel.setScene(fxScene);
|
fxPanel.setScene(fxScene);
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
//show the panel after fully loaded
|
//show the panel after fully loaded
|
||||||
fxPanel.setVisible(true);
|
fxPanel.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corelibs;
|
package org.sleuthkit.autopsy.corelibs;
|
||||||
|
|
||||||
import java.io.File;
|
import com.sun.javafx.PlatformUtil;
|
||||||
import org.hyperic.sigar.Sigar;
|
import org.hyperic.sigar.Sigar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +42,11 @@ public class SigarLoader {
|
|||||||
if (sigar == null) {
|
if (sigar == null) {
|
||||||
try {
|
try {
|
||||||
//rely on netbeans / jna to locate the lib variation for architecture/OS
|
//rely on netbeans / jna to locate the lib variation for architecture/OS
|
||||||
|
if (PlatformUtil.isWindows()) {
|
||||||
System.loadLibrary("libsigar");
|
System.loadLibrary("libsigar");
|
||||||
|
} else {
|
||||||
|
System.loadLibrary("sigar");
|
||||||
|
}
|
||||||
sigar = new Sigar();
|
sigar = new Sigar();
|
||||||
sigar.enableLogging(false); //forces a test
|
sigar.enableLogging(false); //forces a test
|
||||||
|
|
||||||
|
938
Timeline/release/mactime/mactime.pl
Executable file
938
Timeline/release/mactime/mactime.pl
Executable file
@ -0,0 +1,938 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
my $VER="4.1.0";
|
||||||
|
#
|
||||||
|
# This program is based on the 'mactime' program by Dan Farmer and
|
||||||
|
# and the 'mac_daddy' program by Rob Lee.
|
||||||
|
#
|
||||||
|
# It takes as input data from either 'ils -m' or 'fls -m' (from The Sleuth
|
||||||
|
# Kit) or 'mac-robber'.
|
||||||
|
# Based on the dates as arguments given, the data is sorted by and
|
||||||
|
# printed.
|
||||||
|
#
|
||||||
|
# The Sleuth Kit
|
||||||
|
# Brian Carrier [carrier <at> sleuthkit [dot] org]
|
||||||
|
# Copyright (c) 2003-2012 Brian Carrier. All rights reserved
|
||||||
|
#
|
||||||
|
# TASK
|
||||||
|
# Copyright (c) 2002 Brian Carrier, @stake Inc. All rights reserved
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The modifications to the original mactime are distributed under
|
||||||
|
# the Common Public License 1.0
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Copyright 1999 by Dan Farmer. All rights reserved. Some individual
|
||||||
|
# files may be covered by other copyrights (this will be noted in the
|
||||||
|
# file itself.)
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms are permitted
|
||||||
|
# provided that this entire copyright notice is duplicated in all such
|
||||||
|
# copies.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||||
|
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||||
|
#
|
||||||
|
# IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR
|
||||||
|
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
|
||||||
|
use POSIX;
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
my $debug = 0;
|
||||||
|
|
||||||
|
# %month_to_digit = ("Jan", 1, "Feb", 2, "Mar", 3, "Apr", 4, "May", 5, "Jun", 6,
|
||||||
|
# "Jul", 7, "Aug", 8, "Sep", 9, "Oct", 10, "Nov", 11, "Dec", 12);
|
||||||
|
my %digit_to_month = (
|
||||||
|
"01", "Jan", "02", "Feb", "03", "Mar", "04", "Apr",
|
||||||
|
"05", "May", "06", "Jun", "07", "Jul", "08", "Aug",
|
||||||
|
"09", "Sep", "10", "Oct", "11", "Nov", "12", "Dec"
|
||||||
|
);
|
||||||
|
my %digit_to_day = (
|
||||||
|
"0", "Sun", "1", "Mon", "2", "Tue", "3", "Wed",
|
||||||
|
"4", "Thu", "5", "Fri", "6", "Sat"
|
||||||
|
);
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
print <<EOF;
|
||||||
|
mactime [-b body_file] [-p password_file] [-g group_file] [-i day|hour idx_file] [-d] [-h] [-V] [-y] [-z TIME_ZONE] [DATE]
|
||||||
|
-b: Specifies the body file location, else STDIN is used
|
||||||
|
-d: Output in comma delimited format
|
||||||
|
-h: Display a header with session information
|
||||||
|
-i [day | hour] file: Specifies the index file with a summary of results
|
||||||
|
-y: Dates are displayed in ISO 8601 format
|
||||||
|
-m: Dates have month as number instead of word (does not work with -y)
|
||||||
|
-z: Specify the timezone the data came from (in the local system format) (does not work with -y)
|
||||||
|
-g: Specifies the group file location, else GIDs are used
|
||||||
|
-p: Specifies the password file location, else UIDs are used
|
||||||
|
-V: Prints the version to STDOUT
|
||||||
|
[DATE]: starting date (yyyy-mm-dd) or range (yyyy-mm-dd..yyyy-mm-dd)
|
||||||
|
EOF
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub version {
|
||||||
|
print "The Sleuth Kit ver $VER\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $BODY = "";
|
||||||
|
my $GROUP = "";
|
||||||
|
my $PASSWD = "";
|
||||||
|
my $TIME = "";
|
||||||
|
my $INDEX = ""; # File name of index
|
||||||
|
my $INDEX_DAY = 1; # Daily index (for $INDEX_TYPE)
|
||||||
|
my $INDEX_HOUR = 2;
|
||||||
|
my $INDEX_TYPE = $INDEX_DAY; # Saved to type of index
|
||||||
|
my $COMMA = 0; # Comma delimited output
|
||||||
|
|
||||||
|
my $iso8601 = 0;
|
||||||
|
my $month_num = 0;
|
||||||
|
my $header = 0;
|
||||||
|
|
||||||
|
my $in_seconds = 0;
|
||||||
|
my $out_seconds = 0;
|
||||||
|
my %timestr2macstr;
|
||||||
|
my %file2other;
|
||||||
|
|
||||||
|
my %gid2names = ();
|
||||||
|
my %uid2names = ();
|
||||||
|
|
||||||
|
my $_HAS_DATETIME_TIMEZONE = 0;
|
||||||
|
|
||||||
|
eval "use DateTime::TimeZone";
|
||||||
|
if ($@) {
|
||||||
|
$_HAS_DATETIME_TIMEZONE = 0;
|
||||||
|
} else {
|
||||||
|
$_HAS_DATETIME_TIMEZONE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_timezone_list() {
|
||||||
|
my @t_list;
|
||||||
|
if ( ! $_HAS_DATETIME_TIMEZONE ) {
|
||||||
|
return @t_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( DateTime::TimeZone->all_names() ) {
|
||||||
|
push( @t_list, $_ );
|
||||||
|
}
|
||||||
|
foreach( keys( %{DateTime::TimeZone->links()}) ) {
|
||||||
|
push( @t_list, $_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
return sort { $a cmp $b } @t_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() if (scalar(@ARGV) == 0);
|
||||||
|
|
||||||
|
while ((scalar(@ARGV) > 0) && (($_ = $ARGV[0]) =~ /^-(.)(.*)/)) {
|
||||||
|
|
||||||
|
# Body File
|
||||||
|
if (/^-b$/) {
|
||||||
|
shift(@ARGV);
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
$BODY = $ARGV[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "-b requires body file argument\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif (/^-d$/) {
|
||||||
|
$COMMA = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Group File
|
||||||
|
elsif (/^-g$/) {
|
||||||
|
shift(@ARGV);
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
&'load_group_info($ARGV[0]);
|
||||||
|
$GROUP = $ARGV[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "-g requires group file argument\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Password File
|
||||||
|
elsif (/^-p$/) {
|
||||||
|
shift(@ARGV);
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
&'load_passwd_info($ARGV[0]);
|
||||||
|
$PASSWD = $ARGV[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "-p requires password file argument\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif (/^-h$/) {
|
||||||
|
$header = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Index File
|
||||||
|
elsif (/^-i$/) {
|
||||||
|
shift(@ARGV);
|
||||||
|
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
|
||||||
|
# Find out what type
|
||||||
|
if ($ARGV[0] eq "day") {
|
||||||
|
$INDEX_TYPE = $INDEX_DAY;
|
||||||
|
}
|
||||||
|
elsif ($ARGV[0] eq "hour") {
|
||||||
|
$INDEX_TYPE = $INDEX_HOUR;
|
||||||
|
}
|
||||||
|
shift(@ARGV);
|
||||||
|
unless (defined $ARGV[0]) {
|
||||||
|
print "-i requires index file argument\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
$INDEX = $ARGV[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "-i requires index file argument and type\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
open(INDEX, ">$INDEX") or die "Can not open $INDEX";
|
||||||
|
}
|
||||||
|
elsif (/^-V$/) {
|
||||||
|
version();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
elsif (/^-m$/) {
|
||||||
|
$month_num = 1;
|
||||||
|
}
|
||||||
|
elsif (/^-y$/) {
|
||||||
|
$iso8601 = 1;
|
||||||
|
}
|
||||||
|
elsif (/^-z$/) {
|
||||||
|
shift(@ARGV);
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
my $tz = "$ARGV[0]";
|
||||||
|
|
||||||
|
if ($tz =~ m/^list$/i) {
|
||||||
|
if ($_HAS_DATETIME_TIMEZONE) {
|
||||||
|
my $txt = "
|
||||||
|
-----------------------------------
|
||||||
|
TIMEZONE LIST
|
||||||
|
-----------------------------------\n";
|
||||||
|
foreach ( get_timezone_list() ) {
|
||||||
|
$txt .= $_ . "\n";
|
||||||
|
}
|
||||||
|
print( $txt );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "DateTime module not loaded -- cannot list timezones\n";
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
# validate the string if we have DateTime module
|
||||||
|
elsif ($_HAS_DATETIME_TIMEZONE) {
|
||||||
|
my $realtz = 0;
|
||||||
|
foreach ( get_timezone_list() ) {
|
||||||
|
if ($tz =~ m/^$_$/i) {
|
||||||
|
$realtz = $_;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($realtz) {
|
||||||
|
$ENV{TZ} = $realtz;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "invalid timezone provided. Use -z to list valid timezones.\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# blindly take it otherwise
|
||||||
|
else {
|
||||||
|
$ENV{TZ} = $tz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "-z requires the time zone argument\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Unknown option: $_\n";
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
shift(@ARGV);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Was the time given
|
||||||
|
if (defined $ARGV[0]) {
|
||||||
|
my $t_in;
|
||||||
|
my $t_out;
|
||||||
|
|
||||||
|
$TIME = $ARGV[0];
|
||||||
|
if ($ARGV[0] =~ /\.\./) {
|
||||||
|
($t_in, $t_out) = split(/\.\./, $ARGV[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$t_in = $ARGV[0];
|
||||||
|
$t_out = 0;
|
||||||
|
}
|
||||||
|
$in_seconds = parse_isodate($t_in);
|
||||||
|
die "Invalid Date: $t_in\n" if ($in_seconds < 0);
|
||||||
|
|
||||||
|
if ($t_out) {
|
||||||
|
$out_seconds = parse_isodate($t_out);
|
||||||
|
die "Invalid Date: $t_out\n" if ($out_seconds < 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$out_seconds = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$in_seconds = 0;
|
||||||
|
$out_seconds = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print header info
|
||||||
|
print_header() if ($header == 1);
|
||||||
|
|
||||||
|
# Print the index header
|
||||||
|
if ($INDEX ne "") {
|
||||||
|
my $time_str = "";
|
||||||
|
if ($INDEX_TYPE == $INDEX_DAY) {
|
||||||
|
$time_str = "Daily";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$time_str = "Hourly";
|
||||||
|
}
|
||||||
|
if ($BODY ne "") {
|
||||||
|
print INDEX "$time_str Summary for Timeline of $BODY\n\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print INDEX "$time_str Summary for Timeline of STDIN\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read_body();
|
||||||
|
|
||||||
|
print_tl();
|
||||||
|
|
||||||
|
################ SUBROUTINES ##################
|
||||||
|
|
||||||
|
#convert yyyy-mm-dd string to Unix date
|
||||||
|
sub parse_isodate {
|
||||||
|
my $iso_date = shift;
|
||||||
|
|
||||||
|
my $sec = 0;
|
||||||
|
my $min = 0;
|
||||||
|
my $hour = 0;
|
||||||
|
my $wday = 0;
|
||||||
|
my $yday = 0;
|
||||||
|
if ($iso_date =~ /^(\d\d\d\d)\-(\d\d)\-(\d\d)$/) {
|
||||||
|
return mktime($sec, $min, $hour, $3, $2 - 1, $1 - 1900, $wday, $yday);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read the body file from the BODY variable
|
||||||
|
sub read_body {
|
||||||
|
|
||||||
|
# Read the body file from STDIN or the -b specified body file
|
||||||
|
if ($BODY ne "") {
|
||||||
|
open(BODY, "<$BODY") or die "Can't open $BODY";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
open(BODY, "<&STDIN") or die "Can't dup STDIN";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (<BODY>) {
|
||||||
|
next if ((/^\#/) || (/^\s+$/));
|
||||||
|
|
||||||
|
chomp;
|
||||||
|
|
||||||
|
my (
|
||||||
|
$tmp1, $file, $st_ino, $st_ls,
|
||||||
|
$st_uid, $st_gid, $st_size, $st_atime,
|
||||||
|
$st_mtime, $st_ctime, $st_crtime, $tmp2
|
||||||
|
)
|
||||||
|
= &tm_split($_);
|
||||||
|
|
||||||
|
# Sanity check so that we ignore the header entries
|
||||||
|
next unless ((defined $st_ino) && ($st_ino =~ /[\d-]+/));
|
||||||
|
next unless ((defined $st_uid) && ($st_uid =~ /\d+/));
|
||||||
|
next unless ((defined $st_gid) && ($st_gid =~ /\d+/));
|
||||||
|
next unless ((defined $st_size) && ($st_size =~ /\d+/));
|
||||||
|
next unless ((defined $st_mtime) && ($st_mtime =~ /\d+/));
|
||||||
|
next unless ((defined $st_atime) && ($st_atime =~ /\d+/));
|
||||||
|
next unless ((defined $st_ctime) && ($st_ctime =~ /\d+/));
|
||||||
|
next unless ((defined $st_crtime) && ($st_crtime =~ /\d+/));
|
||||||
|
|
||||||
|
# we need *some* value in mactimes!
|
||||||
|
next if (!$st_atime && !$st_mtime && !$st_ctime && !$st_crtime);
|
||||||
|
|
||||||
|
# Skip if these are all too early
|
||||||
|
next
|
||||||
|
if ( ($st_mtime < $in_seconds)
|
||||||
|
&& ($st_atime < $in_seconds)
|
||||||
|
&& ($st_ctime < $in_seconds)
|
||||||
|
&& ($st_crtime < $in_seconds));
|
||||||
|
|
||||||
|
# add leading zeros to timestamps because we will later sort
|
||||||
|
# these using a string-based comparison
|
||||||
|
$st_mtime = sprintf("%.10d", $st_mtime);
|
||||||
|
$st_atime = sprintf("%.10d", $st_atime);
|
||||||
|
$st_ctime = sprintf("%.10d", $st_ctime);
|
||||||
|
$st_crtime = sprintf("%.10d", $st_crtime);
|
||||||
|
|
||||||
|
# Put all the times in one big array along with the inode and
|
||||||
|
# name (they are used in the final sorting)
|
||||||
|
|
||||||
|
# If the date on the file is too old, don't put it in the array
|
||||||
|
my $post = ",$st_ino,$file";
|
||||||
|
|
||||||
|
if ($out_seconds) {
|
||||||
|
$timestr2macstr{"$st_mtime$post"} .= "m"
|
||||||
|
if (
|
||||||
|
($st_mtime >= $in_seconds)
|
||||||
|
&& ($st_mtime < $out_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_mtime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_mtime$post"} !~ /m/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_atime$post"} .= "a"
|
||||||
|
if (
|
||||||
|
($st_atime >= $in_seconds)
|
||||||
|
&& ($st_atime < $out_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_atime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_atime$post"} !~ /a/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_ctime$post"} .= "c"
|
||||||
|
if (
|
||||||
|
($st_ctime >= $in_seconds)
|
||||||
|
&& ($st_ctime < $out_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_ctime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_ctime$post"} !~ /c/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_crtime$post"} .= "b"
|
||||||
|
if (
|
||||||
|
($st_crtime >= $in_seconds)
|
||||||
|
&& ($st_crtime < $out_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_crtime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_crtime$post"} !~ /b/))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$timestr2macstr{"$st_mtime$post"} .= "m"
|
||||||
|
if (
|
||||||
|
($st_mtime >= $in_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_mtime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_mtime$post"} !~ /m/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_atime$post"} .= "a"
|
||||||
|
if (
|
||||||
|
($st_atime >= $in_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_atime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_atime$post"} !~ /a/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_ctime$post"} .= "c"
|
||||||
|
if (
|
||||||
|
($st_ctime >= $in_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_ctime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_ctime$post"} !~ /c/))
|
||||||
|
);
|
||||||
|
|
||||||
|
$timestr2macstr{"$st_crtime$post"} .= "b"
|
||||||
|
if (
|
||||||
|
($st_crtime >= $in_seconds)
|
||||||
|
&& ( (!(exists $timestr2macstr{"$st_crtime$post"}))
|
||||||
|
|| ($timestr2macstr{"$st_crtime$post"} !~ /b/))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# if the UID or GID is not in the array then add it.
|
||||||
|
# these are filled if the -p or -g options are given
|
||||||
|
$uid2names{$st_uid} = $st_uid
|
||||||
|
unless (defined $uid2names{$st_uid});
|
||||||
|
$gid2names{$st_gid} = $st_gid
|
||||||
|
unless (defined $gid2names{$st_gid});
|
||||||
|
|
||||||
|
#
|
||||||
|
# put /'s between multiple UID/GIDs
|
||||||
|
#
|
||||||
|
$uid2names{$st_uid} =~ s@\s@/@g;
|
||||||
|
$gid2names{$st_gid} =~ s@\s@/@g;
|
||||||
|
|
||||||
|
$file2other{$file} =
|
||||||
|
"$st_ls:$uid2names{$st_uid}:$gid2names{$st_gid}:$st_size";
|
||||||
|
}
|
||||||
|
|
||||||
|
close BODY;
|
||||||
|
} # end of read_body
|
||||||
|
|
||||||
|
sub print_header {
|
||||||
|
return if ($header == 0);
|
||||||
|
|
||||||
|
print "The Sleuth Kit mactime Timeline\n";
|
||||||
|
|
||||||
|
print "Input Source: ";
|
||||||
|
if ($BODY eq "") {
|
||||||
|
print "STDIN\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "$BODY\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Time: $TIME\t\t" if ($TIME ne "");
|
||||||
|
|
||||||
|
if ($ENV{TZ} eq "") {
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Timezone: $ENV{TZ}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "passwd File: $PASSWD" if ($PASSWD ne "");
|
||||||
|
if ($GROUP ne "") {
|
||||||
|
print "\t" if ($PASSWD ne "");
|
||||||
|
print "group File: $GROUP";
|
||||||
|
}
|
||||||
|
print "\n" if (($PASSWD ne "") || ($GROUP ne ""));
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Print the time line
|
||||||
|
#
|
||||||
|
sub print_tl {
|
||||||
|
|
||||||
|
my $prev_day = ""; # has the format of 'day day_week mon year'
|
||||||
|
my $prev_hour = ""; # has just the hour and is used for hourly index
|
||||||
|
my $prev_cnt = 0;
|
||||||
|
my $old_date_string = "";
|
||||||
|
|
||||||
|
my $delim = ":";
|
||||||
|
if ($COMMA != 0) {
|
||||||
|
print "Date,Size,Type,Mode,UID,GID,Meta,File Name\n";
|
||||||
|
$delim = ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cycle through the files and print them in sorted order.
|
||||||
|
# Note that we sort using a string comparison because the keys
|
||||||
|
# also contain the inode and file name
|
||||||
|
for my $key (sort { $a cmp $b } keys %timestr2macstr) {
|
||||||
|
my $time;
|
||||||
|
my $inode;
|
||||||
|
my $file;
|
||||||
|
|
||||||
|
if ($key =~ /^(\d+),([\d-]+),(.*)$/) {
|
||||||
|
$time = $1;
|
||||||
|
$inode = $2;
|
||||||
|
$file = $3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
|
||||||
|
if ($iso8601) {
|
||||||
|
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
|
||||||
|
gmtime($time);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
|
||||||
|
localtime($time);
|
||||||
|
}
|
||||||
|
|
||||||
|
# the month here is 0-11, not 1-12, like what we want
|
||||||
|
$mon++;
|
||||||
|
|
||||||
|
print
|
||||||
|
"\t($sec,$min,$hour,MDay: $mday,M: $mon,$year,$wday,$yday,$isdst) = ($time)\n"
|
||||||
|
if $debug;
|
||||||
|
|
||||||
|
#
|
||||||
|
# cosmetic change to make it look like unix dates
|
||||||
|
#
|
||||||
|
$mon = "0$mon" if $mon < 10;
|
||||||
|
$mday = "0$mday" if $mday < 10;
|
||||||
|
$hour = "0$hour" if $hour < 10;
|
||||||
|
$min = "0$min" if $min < 10;
|
||||||
|
$sec = "0$sec" if $sec < 10;
|
||||||
|
|
||||||
|
my $yeart = $year + 1900;
|
||||||
|
|
||||||
|
# How do we print the date?
|
||||||
|
#
|
||||||
|
my $date_string;
|
||||||
|
if ($iso8601) {
|
||||||
|
if ($time == 0) {
|
||||||
|
$date_string = "0000-00-00T00:00:00Z";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date_string =
|
||||||
|
"$yeart-$mon-${mday}T$hour:$min:${sec}Z";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ($time == 0) {
|
||||||
|
$date_string = "Xxx Xxx 00 0000 00:00:00";
|
||||||
|
}
|
||||||
|
elsif ($month_num) {
|
||||||
|
$date_string =
|
||||||
|
"$digit_to_day{$wday} $mon $mday $yeart $hour:$min:$sec";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date_string =
|
||||||
|
"$digit_to_day{$wday} $digit_to_month{$mon} $mday $yeart $hour:$min:$sec";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# However, we only print the date if it's different from the one
|
||||||
|
# above. We need to fill the empty space with blanks, though.
|
||||||
|
#
|
||||||
|
if ($old_date_string eq $date_string) {
|
||||||
|
if ($iso8601) {
|
||||||
|
$date_string = " ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date_string = " ";
|
||||||
|
}
|
||||||
|
$prev_cnt++
|
||||||
|
if ($INDEX ne "");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$old_date_string = $date_string;
|
||||||
|
|
||||||
|
# Indexing code
|
||||||
|
if ($INDEX ne "") {
|
||||||
|
|
||||||
|
# First time it is run
|
||||||
|
if ($prev_day eq "") {
|
||||||
|
$prev_day = "$mday $wday $mon $yeart";
|
||||||
|
$prev_hour = $hour;
|
||||||
|
$prev_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# A new day, so print the results
|
||||||
|
elsif ($prev_day ne "$mday $wday $mon $yeart") {
|
||||||
|
my @prev_vals = split(/ /, $prev_day);
|
||||||
|
|
||||||
|
my $date_str;
|
||||||
|
if ($month_num) {
|
||||||
|
$date_str =
|
||||||
|
"$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$prev_vals[2] "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]}";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date_str =
|
||||||
|
"$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$digit_to_month{$prev_vals[2]} "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$date_str .= " $prev_hour:00:00"
|
||||||
|
if ($INDEX_TYPE == $INDEX_HOUR);
|
||||||
|
|
||||||
|
print INDEX "${date_str}${delim} $prev_cnt\n";
|
||||||
|
|
||||||
|
# Reset
|
||||||
|
$prev_cnt = 0;
|
||||||
|
$prev_day = "$mday $wday $mon $yeart";
|
||||||
|
$prev_hour = $hour;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Same day, but new hour
|
||||||
|
elsif (($INDEX_TYPE == $INDEX_HOUR) && ($prev_hour != $hour)) {
|
||||||
|
my @prev_vals = split(/ /, $prev_day);
|
||||||
|
|
||||||
|
if ($month_num) {
|
||||||
|
print INDEX "$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$prev_vals[2] "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]} "
|
||||||
|
. "$prev_hour:00:00${delim} $prev_cnt\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print INDEX "$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$digit_to_month{$prev_vals[2]} "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]} "
|
||||||
|
. "$prev_hour:00:00${delim} $prev_cnt\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reset
|
||||||
|
$prev_cnt = 0;
|
||||||
|
$prev_hour = $hour;
|
||||||
|
}
|
||||||
|
$prev_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Muck around with the [mac]times string to make it pretty.
|
||||||
|
#
|
||||||
|
my $mactime_tmp = $timestr2macstr{$key};
|
||||||
|
my $mactime = "";
|
||||||
|
if ($mactime_tmp =~ /m/) {
|
||||||
|
$mactime = "m";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mactime = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mactime_tmp =~ /a/) {
|
||||||
|
$mactime .= "a";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mactime .= ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mactime_tmp =~ /c/) {
|
||||||
|
$mactime .= "c";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mactime .= ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mactime_tmp =~ /b/) {
|
||||||
|
$mactime .= "b";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mactime .= ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($ls, $uids, $groups, $size) = split(/:/, $file2other{$file});
|
||||||
|
|
||||||
|
print "FILE: $file MODES: $ls U: $uids G: $groups S: $size\n"
|
||||||
|
if $debug;
|
||||||
|
|
||||||
|
if ($COMMA == 0) {
|
||||||
|
printf("%s %8s %3s %s %-8s %-8s %-8s %s\n",
|
||||||
|
$date_string, $size, $mactime, $ls, $uids, $groups, $inode,
|
||||||
|
$file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# escape any quotes in filename
|
||||||
|
my $file_tmp = $file;
|
||||||
|
$file_tmp =~ s/\"/\"\"/g;
|
||||||
|
printf("%s,%s,%s,%s,%s,%s,%s,\"%s\"\n",
|
||||||
|
$old_date_string, $size, $mactime, $ls, $uids, $groups, $inode,
|
||||||
|
$file_tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Finish the index page for the last entry
|
||||||
|
if (($INDEX ne "") && ($prev_cnt > 0)) {
|
||||||
|
my @prev_vals = split(/ /, $prev_day);
|
||||||
|
|
||||||
|
my $date_str;
|
||||||
|
if ($month_num) {
|
||||||
|
$date_str =
|
||||||
|
"$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$prev_vals[2] "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]}";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date_str =
|
||||||
|
"$digit_to_day{$prev_vals[1]} "
|
||||||
|
. "$digit_to_month{$prev_vals[2]} "
|
||||||
|
. "$prev_vals[0] ${prev_vals[3]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$date_str .= " $prev_hour:00:00"
|
||||||
|
if ($INDEX_TYPE == $INDEX_HOUR);
|
||||||
|
|
||||||
|
print INDEX "${date_str}${delim} $prev_cnt\n";
|
||||||
|
close INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Routines for reading and caching user and group information. These
|
||||||
|
# are used in multiple programs... it caches the info once, then hopefully
|
||||||
|
# won't be used again.
|
||||||
|
#
|
||||||
|
# Steve Romig, May 1991.
|
||||||
|
#
|
||||||
|
# Provides a bunch of routines and a bunch of arrays. Routines
|
||||||
|
# (and their usage):
|
||||||
|
#
|
||||||
|
# load_passwd_info($use_getent, $file_name)
|
||||||
|
#
|
||||||
|
# loads user information into the %uname* and %uid* arrays
|
||||||
|
# (see below).
|
||||||
|
#
|
||||||
|
# If $use_getent is non-zero:
|
||||||
|
# get the info via repeated 'getpwent' calls. This can be
|
||||||
|
# *slow* on some hosts, especially if they are running as a
|
||||||
|
# YP (NIS) client.
|
||||||
|
# If $use_getent is 0:
|
||||||
|
# if $file_name is "", then get the info from reading the
|
||||||
|
# results of "ypcat passwd" and from /etc/passwd. Otherwise,
|
||||||
|
# read the named file. The file should be in passwd(5)
|
||||||
|
# format.
|
||||||
|
#
|
||||||
|
# load_group_info($use_gentent, $file_name)
|
||||||
|
#
|
||||||
|
# is similar to load_passwd_info.
|
||||||
|
#
|
||||||
|
# Information is stored in several convenient associative arrays:
|
||||||
|
#
|
||||||
|
# %uid2names Assoc array, indexed by uid, value is list of
|
||||||
|
# user names with that uid, in form "name name
|
||||||
|
# name...".
|
||||||
|
#
|
||||||
|
# %gid2members Assoc array, indexed by gid, value is list of
|
||||||
|
# group members in form "name name name..."
|
||||||
|
#
|
||||||
|
# %gname2gid Assoc array, indexed by group name, value is
|
||||||
|
# matching gid.
|
||||||
|
#
|
||||||
|
# %gid2names Assoc array, indexed by gid, value is the
|
||||||
|
# list of group names with that gid in form
|
||||||
|
# "name name name...".
|
||||||
|
#
|
||||||
|
# You can also use routines named the same as the arrays - pass the index
|
||||||
|
# as the arg, get back the value. If you use this, get{gr|pw}{uid|gid|nam}
|
||||||
|
# will be used to lookup entries that aren't found in the cache.
|
||||||
|
#
|
||||||
|
# To be done:
|
||||||
|
# probably ought to add routines to deal with full names.
|
||||||
|
# maybe there ought to be some anal-retentive checking of password
|
||||||
|
# and group entries.
|
||||||
|
# probably ought to cache get{pw|gr}{nam|uid|gid} lookups also.
|
||||||
|
# probably ought to avoid overwriting existing entries (eg, duplicate
|
||||||
|
# names in password file would collide in the tables that are
|
||||||
|
# indexed by name).
|
||||||
|
#
|
||||||
|
# Disclaimer:
|
||||||
|
# If you use YP and you use netgroup entries such as
|
||||||
|
# +@servers::::::
|
||||||
|
# +:*:::::/usr/local/utils/messages
|
||||||
|
# then loading the password file in with &load_passwd_info(0) will get
|
||||||
|
# you mostly correct YP stuff *except* that it won't do the password and
|
||||||
|
# shell substitutions as you'd expect. You might want to use
|
||||||
|
# &load_passwd_info(1) instead to use getpwent calls to do the lookups,
|
||||||
|
# which would be more correct.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# minor changes to make it fit with the TCT program, 9/25/99, - dan
|
||||||
|
# A whole lot removed to clean it up for TSK - July 2008 - Brian
|
||||||
|
#
|
||||||
|
|
||||||
|
package main;
|
||||||
|
|
||||||
|
my $passwd_loaded = 0; # flags to use to avoid reloading everything
|
||||||
|
my $group_loaded = 0; # unnecessarily...
|
||||||
|
|
||||||
|
#
|
||||||
|
# Update user information for the user named $name. We cache the password,
|
||||||
|
# uid, login group, home directory and shell.
|
||||||
|
#
|
||||||
|
|
||||||
|
sub add_pw_info {
|
||||||
|
my ($name, $tmp, $uid) = @_;
|
||||||
|
|
||||||
|
if ((defined $name) && ($name ne "")) {
|
||||||
|
|
||||||
|
if ((defined $uid) && ($uid ne "")) {
|
||||||
|
if (defined($uid2names{$uid})) {
|
||||||
|
$uid2names{$uid} .= " $name";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$uid2names{$uid} = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Update group information for the group named $name. We cache the gid
|
||||||
|
# and the list of group members.
|
||||||
|
#
|
||||||
|
|
||||||
|
sub add_gr_info {
|
||||||
|
my ($name, $tmp, $gid) = @_;
|
||||||
|
|
||||||
|
if ((defined $name) && ($name ne "")) {
|
||||||
|
|
||||||
|
if ((defined $gid) && ($gid ne "")) {
|
||||||
|
if (defined($gid2names{$gid})) {
|
||||||
|
$gid2names{$gid} .= " $name";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$gid2names{$gid} = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub load_passwd_info {
|
||||||
|
my ($file_name) = @_;
|
||||||
|
my (@pw_info);
|
||||||
|
|
||||||
|
if ($passwd_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$passwd_loaded = 1;
|
||||||
|
|
||||||
|
open(FILE, $file_name)
|
||||||
|
|| die "can't open $file_name";
|
||||||
|
|
||||||
|
while (<FILE>) {
|
||||||
|
chop;
|
||||||
|
|
||||||
|
if ($_ !~ /^\+/) {
|
||||||
|
&add_pw_info(split(/:/));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub load_group_info {
|
||||||
|
my ($file_name) = @_;
|
||||||
|
my (@gr_info);
|
||||||
|
|
||||||
|
if ($group_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$group_loaded = 1;
|
||||||
|
|
||||||
|
open(FILE, $file_name)
|
||||||
|
|| die "can't open $file_name";
|
||||||
|
|
||||||
|
while (<FILE>) {
|
||||||
|
chop;
|
||||||
|
if ($_ !~ /^\+/) {
|
||||||
|
&add_gr_info(split(/:/));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Split a time machine record.
|
||||||
|
#
|
||||||
|
sub tm_split {
|
||||||
|
my ($line) = @_;
|
||||||
|
my (@fields);
|
||||||
|
|
||||||
|
for (@fields = split(/\|/, $line)) {
|
||||||
|
s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/egis;
|
||||||
|
}
|
||||||
|
return @fields;
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline;
|
package org.sleuthkit.autopsy.timeline;
|
||||||
|
|
||||||
import com.sun.javafx.application.PlatformImpl;
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
@ -86,6 +85,7 @@ import org.openide.util.actions.Presenter;
|
|||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.core.Installer;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
import org.sleuthkit.autopsy.corecomponents.DataContentPanel;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -98,7 +98,6 @@ import org.sleuthkit.autopsy.datamodel.FileNode;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ -147,11 +146,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
public Timeline() {
|
public Timeline() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
org.sleuthkit.autopsy.core.Installer coreInstaller =
|
fxInited = Installer.isJavaFxInited();
|
||||||
ModuleInstall.findObject(org.sleuthkit.autopsy.core.Installer.class, false);
|
|
||||||
if (coreInstaller != null) {
|
|
||||||
fxInited = coreInstaller.isJavaFxInited();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +206,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
//JavaFX thread
|
//JavaFX thread
|
||||||
//JavaFX components MUST be run in the JavaFX thread, otherwise massive amounts of exceptions will be thrown and caught. Liable to freeze up and crash.
|
//JavaFX components MUST be run in the JavaFX thread, otherwise massive amounts of exceptions will be thrown and caught. Liable to freeze up and crash.
|
||||||
//Components can be declared whenever, but initialization and manipulation must take place here.
|
//Components can be declared whenever, but initialization and manipulation must take place here.
|
||||||
PlatformImpl.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -1044,18 +1039,23 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String makeMacTime(String pathToBodyFile) {
|
private String makeMacTime(String pathToBodyFile) {
|
||||||
|
String cmdpath = "";
|
||||||
String macpath = "";
|
String macpath = "";
|
||||||
|
String[] mactimeArgs;
|
||||||
final String machome = macRoot.getAbsolutePath();
|
final String machome = macRoot.getAbsolutePath();
|
||||||
pathToBodyFile = PlatformUtil.getOSFilePath(pathToBodyFile);
|
pathToBodyFile = PlatformUtil.getOSFilePath(pathToBodyFile);
|
||||||
if (PlatformUtil.isWindowsOS()) {
|
if (PlatformUtil.isWindowsOS()) {
|
||||||
macpath = machome + java.io.File.separator + "mactime.exe";
|
macpath = machome + java.io.File.separator + "mactime.exe";
|
||||||
macpath = PlatformUtil.getOSFilePath(macpath);
|
cmdpath = PlatformUtil.getOSFilePath(cmdpath);
|
||||||
|
mactimeArgs = new String[]{"-b", pathToBodyFile, "-d", "-y"};
|
||||||
} else {
|
} else {
|
||||||
macpath = "perl " + machome + java.io.File.separator + "mactime.pl";
|
cmdpath = "perl";
|
||||||
|
macpath = machome + java.io.File.separator + "mactime.pl";
|
||||||
|
mactimeArgs = new String[]{macpath, "-b", pathToBodyFile, "-d", "-y"};
|
||||||
}
|
}
|
||||||
|
|
||||||
String macfile = moduleDir.getAbsolutePath() + java.io.File.separator + mactimeFileName;
|
String macfile = moduleDir.getAbsolutePath() + java.io.File.separator + mactimeFileName;
|
||||||
String[] mactimeArgs = new String[]{"-b", pathToBodyFile, "-d", "-y"};
|
|
||||||
|
|
||||||
String output = "";
|
String output = "";
|
||||||
ExecUtil execUtil = new ExecUtil();
|
ExecUtil execUtil = new ExecUtil();
|
||||||
@ -1063,7 +1063,7 @@ public class Timeline extends CallableSystemAction implements Presenter.Toolbar,
|
|||||||
try {
|
try {
|
||||||
//JavaSystemCaller.Exec.execute("\"" + command + "\"");
|
//JavaSystemCaller.Exec.execute("\"" + command + "\"");
|
||||||
writer = new FileWriter(macfile);
|
writer = new FileWriter(macfile);
|
||||||
execUtil.execute(writer, macpath, mactimeArgs);
|
execUtil.execute(writer, cmdpath, mactimeArgs);
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
logger.log(Level.WARNING, "Mactime process was interrupted by user", ie);
|
logger.log(Level.WARNING, "Mactime process was interrupted by user", ie);
|
||||||
return null;
|
return null;
|
||||||
|
BIN
branding_autopsy/icon.icns
Normal file
BIN
branding_autopsy/icon.icns
Normal file
Binary file not shown.
@ -86,7 +86,7 @@
|
|||||||
<copy file="${basedir}/branding_${app.name}/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
|
<copy file="${basedir}/branding_${app.name}/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
|
||||||
|
|
||||||
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
|
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
|
||||||
<property name="jvm.options" value=""--branding ${app.name} -J-Xms24m -J-Xmx512m -J-XX:MaxPermSize=128M -J-Xverify:none"" />
|
<property name="jvm.options" value=""--branding ${app.name} -J-Xms24m -J-Xmx512m -J-XX:MaxPermSize=128M -J-Xverify:none -J-Xdock:name=${app.title}"" />
|
||||||
<propertyfile file="${app.property.file}">
|
<propertyfile file="${app.property.file}">
|
||||||
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
|
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
|
||||||
<entry key="default_options" value="@JVM_OPTIONS" />
|
<entry key="default_options" value="@JVM_OPTIONS" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user