WManageBookmarks.saveBookmarks();
}
});
// wire listener to manage when bookmarks are available for export
BEViewer.bookmarksModel.bookmarksComboBoxModel.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent e) {
miExportBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
public void intervalAdded(ListDataEvent e) {
miExportBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
public void intervalRemoved(ListDataEvent e) {
miExportBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
});
miExportBookmarks.setEnabled(false);
// file|<separator>
file.addSeparator();
// file|Import Work Settings
mi = new JMenuItem("Import Work Settings\u2026"); // ...
file.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
WImportWorkSettings.openWindow();
}
});
// file|Export Work Settings
mi = new JMenuItem("Export Work Settings\u2026"); // ...
file.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
WExportWorkSettings.openWindow();
}
});
// file|<separator>
file.addSeparator();
// file|Print Range
miPrintFeature = new JMenuItem("Print Range\u2026", BEIcons.PRINT_FEATURE_16); // ...
miPrintFeature.setEnabled(false);
file.add(miPrintFeature);
miPrintFeature.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.printRange();
}
});
// wire listener to know when a feature is available for printing
BEViewer.rangeSelectionManager.addRangeSelectionManagerChangedListener(new Observer() {
public void update(Observable o, Object arg) {
miPrintFeature.setEnabled(BEViewer.rangeSelectionManager.hasSelection());
}
});
// file|<separator>
file.addSeparator();
// file Quit
mi = new JMenuItem("Quit", BEIcons.EXIT_16);
file.add(mi);
mi.setAccelerator(KEYSTROKE_Q);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
// close down BEViewer
BEViewer.doClose();
}
});
// edit
JMenu edit = new JMenu("Edit");
add(edit);
// edit|copy
miCopy = new JMenuItem("Copy", BEIcons.COPY_16);
miCopy.setEnabled(false);
edit.add(miCopy);
miCopy.setAccelerator(KEYSTROKE_C);
miCopy.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
// put text onto System Clipboard
RangeSelectionManager.setSystemClipboard(BEViewer.rangeSelectionManager.getSelection());
}
});
// wire listener to manage when a buffer is available to copy
BEViewer.rangeSelectionManager.addRangeSelectionManagerChangedListener(new Observer() {
public void update(Observable o, Object arg) {
miCopy.setEnabled(BEViewer.rangeSelectionManager.hasSelection());
}
});
// edit|<separator>
edit.addSeparator();
// edit|clear all bookmarks
miClearBookmarks = new JMenuItem("Clear Bookmarks");
edit.add(miClearBookmarks);
miClearBookmarks.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.bookmarksModel.clear();
}
});
miClearBookmarks.setEnabled(false);
// wire listener to know when bookmarks are empty
BEViewer.bookmarksModel.bookmarksComboBoxModel.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent e) {
miClearBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
public void intervalAdded(ListDataEvent e) {
miClearBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
public void intervalRemoved(ListDataEvent e) {
miClearBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
});
// view
JMenu view = new JMenu("View");
add(view);
ButtonGroup imageGroup = new ButtonGroup();
ButtonGroup forensicPathNumericBaseGroup = new ButtonGroup();
ButtonGroup referencedFeaturesGroup = new ButtonGroup();
// view|Toolbar
cbShowToolbar = new JCheckBoxMenuItem("Toolbar");
cbShowToolbar.setSelected(true);
view.add(cbShowToolbar);
cbShowToolbar.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.toolbar.setVisible(cbShowToolbar.isSelected());
}
});
// wire listener to know when the toolbar is visible
BEViewer.toolbar.addToolbarChangedListener(new Observer() {
public void update(Observable o, Object arg) {
cbShowToolbar.setSelected(BEViewer.toolbar.isVisible());
}
});
// view|Image Format
JMenu imageFormatMenu = new JMenu("Image Format");
view.add(imageFormatMenu);
// view|Image Format|Text
rbTextView = new JRadioButtonMenuItem("Text");
imageGroup.add(rbTextView);
imageFormatMenu.add(rbTextView);
rbTextView.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.imageView.setLineFormat(ImageLine.LineFormat.TEXT_FORMAT);
}
});
// view|Image Format|Hex
rbHexView = new JRadioButtonMenuItem("Hex");
imageGroup.add(rbHexView);
imageFormatMenu.add(rbHexView);
rbHexView.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.imageView.setLineFormat(ImageLine.LineFormat.HEX_FORMAT);
}
});
// wire listener to manage which image view type button is selected
BEViewer.imageView.addImageViewChangedListener(new Observer() {
public void update(Observable o, Object arg) {
// this could be changed to act only on ImageView.ChangeType.FORENSIC_PATH_NUMERIC_BASE_CHANGED
ImageLine.LineFormat lineFormat = BEViewer.imageView.getLineFormat();
if (lineFormat == ImageLine.LineFormat.TEXT_FORMAT) {
rbTextView.setSelected(true);
} else if (lineFormat == ImageLine.LineFormat.HEX_FORMAT) {
rbHexView.setSelected(true);
} else {
throw new RuntimeException("invalid image format source");
}
}
});
// view|Forensic Path Numeric Base
JMenu forensicPathNumericBaseMenu = new JMenu("Forensic Path Numeric Base");
view.add(forensicPathNumericBaseMenu);
// view|Forensic Path Numeric Base|Decimal
rbDecimal = new JRadioButtonMenuItem("Decimal");
forensicPathNumericBaseGroup.add(rbDecimal);
forensicPathNumericBaseMenu.add(rbDecimal);
rbDecimal.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.featuresModel.setUseHexPath(false);
BEViewer.referencedFeaturesModel.setUseHexPath(false);
BEViewer.imageView.setUseHexPath(false);
BEViewer.bookmarksModel.fireViewChanged();
}
});
// view|Forensic Path Numeric Base|Hex
rbHex = new JRadioButtonMenuItem("Hexadecimal");
forensicPathNumericBaseGroup.add(rbHex);
forensicPathNumericBaseMenu.add(rbHex);
rbHex.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.featuresModel.setUseHexPath(true);
BEViewer.referencedFeaturesModel.setUseHexPath(true);
BEViewer.imageView.setUseHexPath(true);
BEViewer.bookmarksModel.fireViewChanged();
}
});
// wire listener to manage which forensic path numeric base is shown in the menu
BEViewer.imageView.addImageViewChangedListener(new Observer() {
public void update(Observable o, Object arg) {
if (BEViewer.imageView.getChangeType() == ImageView.ChangeType.FORENSIC_PATH_NUMERIC_BASE_CHANGED) {
boolean isHex = BEViewer.imageView.getUseHexPath();
if (!isHex) {
rbDecimal.setSelected(true);
} else {
rbHex.setSelected(true);
}
}
}
});
// view|Feature Font Size
JMenu featureFontSizeMenu = new JMenu("Feature Font Size");
view.add(featureFontSizeMenu);
// view|Feature Font Size|Zoom In
mi = new JMenuItem("Zoom In");
featureFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.featuresModel.setFontSize(BEViewer.featuresModel.getFontSize() + 1);
BEViewer.referencedFeaturesModel.setFontSize(BEViewer.featuresModel.getFontSize());
}
});
// view|Feature Font Size|Zoom Out
mi = new JMenuItem("Zoom Out");
featureFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
int oldFontSize = BEViewer.featuresModel.getFontSize();
if (oldFontSize > 6) {
BEViewer.featuresModel.setFontSize(oldFontSize - 1);
BEViewer.referencedFeaturesModel.setFontSize(BEViewer.featuresModel.getFontSize());
} else {
WError.showError("Already at minimum font size of " + oldFontSize + ".",
"BEViewer Feature Font Size error", null);
}
}
});
// view|Feature File View|Normal Size
mi = new JMenuItem("Normal Size");
featureFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.featuresModel.setFontSize(BEPreferences.DEFAULT_FEATURE_FONT_SIZE);
BEViewer.referencedFeaturesModel.setFontSize(BEViewer.featuresModel.getFontSize());
}
});
// view|Image Font Size
JMenu imageFontSizeMenu = new JMenu("Image Font Size");
view.add(imageFontSizeMenu);
// view|Image Font Size|Zoom In
mi = new JMenuItem("Zoom In");
imageFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.imageView.setFontSize(BEViewer.imageView.getFontSize() + 1);
}
});
// view|Image Font Size|Zoom Out
mi = new JMenuItem("Zoom Out");
imageFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
int oldFontSize = BEViewer.imageView.getFontSize();
if (oldFontSize > 6) {
BEViewer.imageView.setFontSize(oldFontSize - 1);
} else {
WError.showError("Already at minimum font size of " + oldFontSize + ".",
"BEViewer Image Font Size Size error", null);
}
}
});
// view|Image Font Size|Normal Size
mi = new JMenuItem("Normal Size");
imageFontSizeMenu.add(mi);
mi.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.imageView.setFontSize(BEPreferences.DEFAULT_IMAGE_FONT_SIZE);
}
});
// view|Referenced Features
JMenu referencedFeaturesMenu = new JMenu("Referenced Features");
view.add(referencedFeaturesMenu);
// view|Referenced Features|always visible
rbReferencedFeaturesVisible = new JRadioButtonMenuItem("Always Visible");
referencedFeaturesGroup.add(rbReferencedFeaturesVisible);
referencedFeaturesMenu.add(rbReferencedFeaturesVisible);
rbReferencedFeaturesVisible.setSelected(!BEViewer.reportSelectionManager.isRequestHideReferencedFeatureView());
rbReferencedFeaturesVisible.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.reportSelectionManager.setRequestHideReferencedFeatureView(false);
}
});
// view|Referenced Features|collapsible
rbReferencedFeaturesCollapsible = new JRadioButtonMenuItem("Collapsed when not Referenced");
referencedFeaturesGroup.add(rbReferencedFeaturesCollapsible);
referencedFeaturesMenu.add(rbReferencedFeaturesCollapsible);
rbReferencedFeaturesCollapsible.setSelected(BEViewer.reportSelectionManager.isRequestHideReferencedFeatureView());
rbReferencedFeaturesCollapsible.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.reportSelectionManager.setRequestHideReferencedFeatureView(true);
}
});
// wire listener to manage which visibility mode is shown in the menu
BEViewer.reportSelectionManager.addReportSelectionManagerChangedListener(new Observer() {
public void update(Observable o, Object arg) {
boolean requestHide = BEViewer.reportSelectionManager.isRequestHideReferencedFeatureView();
if (requestHide) {
rbReferencedFeaturesCollapsible.setSelected(true);
} else {
rbReferencedFeaturesVisible.setSelected(true);
}
}
});
// view|Feature Files
JMenu featureFilesMenu = new JMenu("Feature Files");
view.add(featureFilesMenu);
// view|Feature Files|Show Stoplist Files
cbShowStoplistFiles = new JCheckBoxMenuItem("Show Stoplist Files");
featureFilesMenu.add(cbShowStoplistFiles);
cbShowStoplistFiles.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.reportsModel.setIncludeStoplistFiles(cbShowStoplistFiles.getState());
}
});
// wire ReportsModel's report tree model listener to manage when show stoplist files is enabled
BEViewer.reportsModel.getTreeModel().addTreeModelListener(new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent e) {
setShowStoplistVisibility();
}
public void treeNodesInserted(TreeModelEvent e) {
setShowStoplistVisibility();
}
public void treeNodesRemoved(TreeModelEvent e) {
setShowStoplistVisibility();
}
public void treeStructureChanged(TreeModelEvent e) {
setShowStoplistVisibility();
}
private void setShowStoplistVisibility() {
Enumeration<ReportsModel.ReportTreeNode> e = BEViewer.reportsModel.elements();
cbShowStoplistFiles.setSelected(BEViewer.reportsModel.isIncludeStoplistFiles());
}
});
// view|Feature Files|Show Empty Files
cbShowEmptyFiles = new JCheckBoxMenuItem("Show Empty Files");
featureFilesMenu.add(cbShowEmptyFiles);
cbShowEmptyFiles.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
BEViewer.reportsModel.setIncludeEmptyFiles(cbShowEmptyFiles.getState());
}
});
// wire ReportsModel's report tree model listener to manage when show empty files is enabled
BEViewer.reportsModel.getTreeModel().addTreeModelListener(new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent e) {
setShowEmptyFilesVisibility();
}
public void treeNodesInserted(TreeModelEvent e) {
setShowEmptyFilesVisibility();
}
public void treeNodesRemoved(TreeModelEvent e) {
setShowEmptyFilesVisibility();
}
public void treeStructureChanged(TreeModelEvent e) {
setShowEmptyFilesVisibility();
}
private void setShowEmptyFilesVisibility() {
Enumeration<ReportsModel.ReportTreeNode> e = BEViewer.reportsModel.elements();
cbShowEmptyFiles.setSelected(BEViewer.reportsModel.isIncludeEmptyFiles());
}
});
// view|<separator>
view.addSeparator();
// view|Selected Feature
JMenu selectedFeature = new JMenu("Selected Feature");
view.add(selectedFeature);
// view|SelectedFeature|Pan to Start of Path
miPanToStart = new JMenuItem("Pan to Start of Path");
selectedFeature.add(miPanToStart);
miPanToStart.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
// move to start of feature currently in the image model
BEViewer.imageModel.setImageSelection(ForensicPath.getAdjustedPath(
BEViewer.imageView.getImagePage().pageForensicPath, 0));
}
});
miPanToStart.setEnabled(false);
// view|SelectedFeature|Pan to End of Path
miPanToEnd = new JMenuItem("Pan to End of Path");
selectedFeature.add(miPanToEnd);
miPanToEnd.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
// move to end of feature currently in the image model
ImageModel.ImagePage imagePage = BEViewer.imageView.getImagePage();
String pageForensicPath = imagePage.pageForensicPath;
long imageSize = imagePage.imageSize;
long imageEndOffset = (imageSize > 0) ? imageSize - 1 : 0;
BEViewer.imageModel.setImageSelection(ForensicPath.getAdjustedPath(
pageForensicPath, imageEndOffset));
}
});
miPanToEnd.setEnabled(false);
// view|Selected Feature|<separator>
selectedFeature.addSeparator();
// view|Selected Feature|report.xml File
miShowReportFile = new JMenuItem("Show report.xml File");
selectedFeature.add(miShowReportFile);
miShowReportFile.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
// get the currently selected feature line
FeatureLine featureLine = BEViewer.featureLineSelectionManager.getFeatureLineSelection();
if (featureLine.featuresFile == null) {
WError.showError("A Feature must be selected before viewing the Report file.",
"BEViewer Selected Feature error", null);
} else {
try {
File reportFile = new File(featureLine.featuresFile.getParentFile(), "report.xml");
URL url = reportFile.toURI().toURL();
new WURL("Bulk Extractor Viewer Report file " + reportFile.toString(), url);
} catch (Exception exc) {
WError.showError("Unable to read report.xml file.",
"BEViewer Read error", exc);
}
}
}
});
miShowReportFile.setEnabled(false);
// wire action for all view|selected feature items
BEViewer.featureLineSelectionManager.addFeatureLineSelectionManagerChangedListener(new Observer() {
public void update(Observable o, Object arg) {
FeatureLine selectedFeatureLine = BEViewer.featureLineSelectionManager.getFeatureLineSelection();
boolean hasSelection = !selectedFeatureLine.isBlank();
miPanToStart.setEnabled(hasSelection);
miPanToEnd.setEnabled(hasSelection);
miShowReportFile.setEnabled(hasSelection);
}
});
// bookmarks
JMenu bookmarks = new JMenu("Bookmarks");
add(bookmarks);
// bookmarks|Bookmark selected Feature
miAddBookmark = new JMenuItem("Bookmark selected Feature", BEIcons.ADD_BOOKMARK_16); // ...
bookmarks.add(miAddBookmark);
miAddBookmark.setAccelerator(KEYSTROKE_B);
miAddBookmark.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
FeatureLine selectedFeatureLine = BEViewer.featureLineSelectionManager.getFeatureLineSelection();
BEViewer.bookmarksModel.addElement(selectedFeatureLine);
}
});
// a feature line has been selected and may be added as a bookmark
BEViewer.featureLineSelectionManager.addFeatureLineSelectionManagerChangedListener(new Observer() {
public void update(Observable o, Object arg) {
// same as in BEToolbar
// enabled if feature line is not blank and is not already bookmarked
FeatureLine selectedFeatureLine = BEViewer.featureLineSelectionManager.getFeatureLineSelection();
miAddBookmark.setEnabled(!selectedFeatureLine.isBlank()
&& !BEViewer.bookmarksModel.contains(selectedFeatureLine));
}
});
FeatureLine selectedFeatureLine = BEViewer.featureLineSelectionManager.getFeatureLineSelection();
miAddBookmark.setEnabled(!selectedFeatureLine.isBlank()
&& !BEViewer.bookmarksModel.contains(selectedFeatureLine));
// bookmarks|Manage Bookmarks
miManageBookmarks = new JMenuItem("Manage Bookmarks\u2026", BEIcons.MANAGE_BOOKMARKS_16); // ...
bookmarks.add(miManageBookmarks);
miManageBookmarks.setAccelerator(KEYSTROKE_M);
miManageBookmarks.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
WManageBookmarks.openWindow();
}
});
// wire listener to manage when bookmarks are available for management
BEViewer.bookmarksModel.bookmarksComboBoxModel.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent e) {
miManageBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());
}
public void intervalAdded(ListDataEvent e) {
miManageBookmarks.setEnabled(!BEViewer.bookmarksModel.isEmpty());