diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index fce437a96f..caa5ecd386 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -147,3 +147,7 @@ AutopsyOptionsPanel.jLabelNumThreads.text=Number of threads to use for file inge
FXVideoPanel.progress.bufferingCancelled=media buffering was canceled
FXVideoPanel.progress.bufferingInterrupted=media buffering was interrupted
FXVideoPanel.progress.errorWritingVideoToDisk=Error writing video to disk
+DataContentViewerHex.goToOffsetLabel.text=Jump to Offset
+DataContentViewerHex.goToOffsetTextField.text=
+DataContentViewerHex.goToOffsetTextField.msgDlg=Invalid Offset: {0}
+DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue=Cannot jump to the resultant offset
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties
old mode 100644
new mode 100755
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form
index a5663b4644..cd5d9e21d0 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form
@@ -88,9 +88,13 @@
-
+
+
+
+
+
-
+
@@ -108,9 +112,11 @@
+
+
-
-
+
+
@@ -131,6 +137,9 @@
+
+
+
@@ -140,7 +149,7 @@
-
+
@@ -278,6 +287,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
index c7eb83ebd0..11cee38ab4 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
@@ -28,6 +28,8 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextPane;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Utilities;
import org.openide.nodes.Node;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
@@ -94,6 +96,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
return (getSize().width < 400);
}};
this.outputViewPane.setBackground(new java.awt.Color(255, 255, 255)); // to make sure the background color is white
+ this.outputViewPane.requestFocusInWindow();
+ this.outputViewPane.setCursor(Cursor.getDefaultCursor());
totalPageLabel = new javax.swing.JLabel();
ofLabel = new javax.swing.JLabel();
currentPageLabel = new javax.swing.JLabel();
@@ -103,6 +107,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
pageLabel2 = new javax.swing.JLabel();
goToPageTextField = new javax.swing.JTextField();
goToPageLabel = new javax.swing.JLabel();
+ goToOffsetLabel = new javax.swing.JLabel();
+ goToOffsetTextField = new javax.swing.JTextField();
copyMenuItem.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.copyMenuItem.text")); // NOI18N
rightClickMenu.add(copyMenuItem);
@@ -113,7 +119,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
outputViewPane.setEditable(false);
- outputViewPane.setFont(new Font("Courier New", Font.PLAIN, 11)); // NOI18N NON-NLS
+ outputViewPane.setFont(new java.awt.Font("Courier New", 0, 11)); // NOI18N
+ outputViewPane.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
outputViewPane.setMinimumSize(new java.awt.Dimension(700, 20));
outputViewPane.setPreferredSize(new java.awt.Dimension(700, 400));
jScrollPane1.setViewportView(outputViewPane);
@@ -132,28 +139,28 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
pageLabel.setMinimumSize(new java.awt.Dimension(33, 14));
pageLabel.setPreferredSize(new java.awt.Dimension(33, 14));
- prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N NON-NLS
+ prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.prevPageButton.text")); // NOI18N
prevPageButton.setBorderPainted(false);
prevPageButton.setContentAreaFilled(false);
- prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N NON-NLS
+ prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
prevPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
- prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N NON-NLS
+ prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
prevPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
prevPageButtonActionPerformed(evt);
}
});
- nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N NON-NLS
+ nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.nextPageButton.text")); // NOI18N
nextPageButton.setBorderPainted(false);
nextPageButton.setContentAreaFilled(false);
- nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N NON-NLS
+ nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
nextPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
- nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N NON-NLS
+ nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
nextPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextPageButtonActionPerformed(evt);
@@ -174,6 +181,15 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
goToPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToPageLabel.text")); // NOI18N
+ goToOffsetLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetLabel.text")); // NOI18N
+
+ goToOffsetTextField.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetTextField.text")); // NOI18N
+ goToOffsetTextField.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ goToOffsetTextFieldActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout hexViewerPanelLayout = new javax.swing.GroupLayout(hexViewerPanel);
hexViewerPanel.setLayout(hexViewerPanelLayout);
hexViewerPanelLayout.setHorizontalGroup(
@@ -197,8 +213,12 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
.addComponent(goToPageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(205, Short.MAX_VALUE))
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
+ .addGap(18, 18, 18)
+ .addComponent(goToOffsetLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(jScrollPane1)
);
hexViewerPanelLayout.setVerticalGroup(
hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -213,9 +233,11 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(goToPageLabel)
- .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(0, 0, 0)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE))
+ .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(goToOffsetLabel)
+ .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@@ -241,11 +263,13 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
}// //GEN-END:initComponents
private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
- setDataView(currentPage - 1);
+ setDataViewByPageNumber(currentPage - 1);
+ goToPageTextField.setText(Integer.toString(currentPage));
}//GEN-LAST:event_prevPageButtonActionPerformed
private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
- setDataView(currentPage + 1);
+ setDataViewByPageNumber(currentPage + 1);
+ goToPageTextField.setText(Integer.toString(currentPage));
}//GEN-LAST:event_nextPageButtonActionPerformed
private void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageTextFieldActionPerformed
@@ -267,11 +291,59 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
JOptionPane.WARNING_MESSAGE);
return;
}
- setDataView(pageNumber);
+ setDataViewByPageNumber(pageNumber);
}//GEN-LAST:event_goToPageTextFieldActionPerformed
+
+ /***
+ * Calculates the offset relative to the current caret position.
+ * @param userInput the user provided signed offset value.
+ * @return returns the resultant offset value relative to the current caret
+ * position. -1L is returned if the resultant offset cannot be calculated.
+ */
+ private long getOffsetRelativeToCaretPosition(Long userInput) {
+ String userSelectedLine;
+ try {
+ // get the selected line. Extract the current hex offset location.
+ userSelectedLine = outputViewPane.getText().subSequence(
+ Utilities.getRowStart(outputViewPane, outputViewPane.getCaretPosition()),
+ Utilities.getRowEnd(outputViewPane, outputViewPane.getCaretPosition()))
+ .toString();
+ // NOTE: This needs to change if the outputFormat of outputViewPane changes.
+ String hexForUserSelectedLine = userSelectedLine.substring(0, userSelectedLine.indexOf(":"));
+
+ return Long.decode(hexForUserSelectedLine) + userInput;
+ } catch (BadLocationException | StringIndexOutOfBoundsException | NumberFormatException ex) {
+ // thrown in case the caret location is out of the range of the outputViewPane.
+ return -1L;
+ }
+ }
+
+ private void goToOffsetTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToOffsetTextFieldActionPerformed
+ long offset;
+ try {
+ if (goToOffsetTextField.getText().startsWith("+") || goToOffsetTextField.getText().startsWith("-")) {
+ offset = getOffsetRelativeToCaretPosition(Long.decode(goToOffsetTextField.getText()));
+ } else {
+ offset = Long.decode(goToOffsetTextField.getText());
+ }
+ } catch (NumberFormatException ex) {
+ // notify the user and return
+ JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), "DataContentViewerHex.goToOffsetTextField.msgDlg", goToOffsetTextField.getText()));
+ return;
+ }
+
+ if (offset >= 0) {
+ setDataViewByOffset(offset);
+ } else {
+ outputViewPane.setText(NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue"));
+ }
+ }//GEN-LAST:event_goToOffsetTextFieldActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JLabel currentPageLabel;
+ private javax.swing.JLabel goToOffsetLabel;
+ private javax.swing.JTextField goToOffsetTextField;
private javax.swing.JLabel goToPageLabel;
private javax.swing.JTextField goToPageTextField;
private javax.swing.JPanel hexViewerPanel;
@@ -289,26 +361,41 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
/**
- * Sets the DataView (The tabbed panel)
+ * Sets the DataView (The tabbed panel) by page number
*
* @param page Page to display (1-based counting)
*/
- private void setDataView(int page) {
+ private void setDataViewByPageNumber(int page) {
if (this.dataSource == null) {
return;
}
-
if (page == 0) {
return;
}
-
currentPage = page;
long offset = (currentPage - 1) * pageLength;
-
+ setDataView(offset);
+ goToOffsetTextField.setText(Long.toString(offset));
+ }
+ /**
+ * Sets the DataView (The tabbed panel) by offset
+ *
+ * @param page Page to display (1-based counting)
+ */
+ private void setDataViewByOffset(long offset) {
+ if (this.dataSource == null) {
+ return;
+ }
+ currentPage = (int) (offset / pageLength) + 1;
+ setDataView(offset);
+ goToPageTextField.setText(Integer.toString(currentPage));
+ }
+
+ private void setDataView(long offset) {
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- String errorText = null;
+ String errorText = null;
int bytesRead = 0;
if (dataSource.getSize() > 0) {
@@ -316,7 +403,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
bytesRead = dataSource.read(data, offset, pageLength); // read the data
} catch (TskException ex) {
errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset,
- offset + pageLength);
+ offset + pageLength);
logger.log(Level.WARNING, "Error while trying to show the hex content.", ex); //NON-NLS
}
}
@@ -324,25 +411,22 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
// set the data on the bottom and show it
if (bytesRead <= 0) {
errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset,
- offset + pageLength);
+ offset + pageLength);
}
-
// disable or enable the next button
if ((errorText == null) && (currentPage < totalPages)) {
nextPageButton.setEnabled(true);
- }
- else {
+ } else {
nextPageButton.setEnabled(false);
}
if ((errorText == null) && (currentPage > 1)) {
prevPageButton.setEnabled(true);
- }
- else {
+ } else {
prevPageButton.setEnabled(false);
}
-
+
currentPageLabel.setText(Integer.toString(currentPage));
setComponentsVisibility(true); // shows the components that not needed
@@ -350,8 +434,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
if (errorText == null) {
int showLength = bytesRead < pageLength ? bytesRead : (int) pageLength;
outputViewPane.setText(DataConversion.byteArrayToHex(data, showLength, offset));
- }
- else {
+ } else {
outputViewPane.setText(errorText);
}
@@ -379,7 +462,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
}
totalPageLabel.setText(Integer.toString(totalPages));
- this.setDataView(1);
+ this.setDataViewByPageNumber(1);
}
@Override
@@ -423,6 +506,8 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
pageLabel2.setVisible(isVisible);
goToPageTextField.setVisible(isVisible);
goToPageLabel.setVisible(isVisible);
+ goToOffsetTextField.setVisible(isVisible);
+ goToOffsetLabel.setVisible(isVisible);
}
@Override