diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 54204f16fc..8f1c0ac9c1 100644 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -41,9 +41,9 @@ - - - + + + diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index a44d89c6e1..35ce6aada8 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -41,15 +41,15 @@ file.reference.imgscalr-lib-4.2.jar=release/modules/ext/imgscalr-lib-4.2.jar file.reference.javaee-api-5.0-2.jar=release/modules/ext/javaee-api-5.0-2.jar file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.jar file.reference.jcalendarbutton-1.4.6.jar=release/modules/ext/jcalendarbutton-1.4.6.jar -file.reference.jfxtras-common-8.0-r1-javadoc.jar=release/modules/ext/jfxtras-common-8.0-r1-javadoc.jar -file.reference.jfxtras-common-8.0-r1-sources.jar=release/modules/ext/jfxtras-common-8.0-r1-sources.jar -file.reference.jfxtras-common-8.0-r1.jar=release/modules/ext/jfxtras-common-8.0-r1.jar -file.reference.jfxtras-controls-8.0-r1-javadoc.jar=release/modules/ext/jfxtras-controls-8.0-r1-javadoc.jar -file.reference.jfxtras-controls-8.0-r1-sources.jar=release/modules/ext/jfxtras-controls-8.0-r1-sources.jar -file.reference.jfxtras-controls-8.0-r1.jar=release/modules/ext/jfxtras-controls-8.0-r1.jar -file.reference.jfxtras-fxml-8.0-r1-javadoc.jar=release/modules/ext/jfxtras-fxml-8.0-r1-javadoc.jar -file.reference.jfxtras-fxml-8.0-r1-sources.jar=release/modules/ext/jfxtras-fxml-8.0-r1-sources.jar -file.reference.jfxtras-fxml-8.0-r1.jar=release/modules/ext/jfxtras-fxml-8.0-r1.jar +file.reference.jfxtras-common-8.0-r3-javadoc.jar=release/modules/ext/jfxtras-common-8.0-r3-javadoc.jar +file.reference.jfxtras-common-8.0-r3-sources.jar=release/modules/ext/jfxtras-common-8.0-r3-sources.jar +file.reference.jfxtras-common-8.0-r3.jar=release/modules/ext/jfxtras-common-8.0-r3.jar +file.reference.jfxtras-controls-8.0-r3-javadoc.jar=release/modules/ext/jfxtras-controls-8.0-r3-javadoc.jar +file.reference.jfxtras-controls-8.0-r3-sources.jar=release/modules/ext/jfxtras-controls-8.0-r3-sources.jar +file.reference.jfxtras-controls-8.0-r3.jar=release/modules/ext/jfxtras-controls-8.0-r3.jar +file.reference.jfxtras-fxml-8.0-r3-javadoc.jar=release/modules/ext/jfxtras-fxml-8.0-r3-javadoc.jar +file.reference.jfxtras-fxml-8.0-r3-sources.jar=release/modules/ext/jfxtras-fxml-8.0-r3-sources.jar +file.reference.jfxtras-fxml-8.0-r3.jar=release/modules/ext/jfxtras-fxml-8.0-r3.jar file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.joda-time-2.4-javadoc.jar=release/modules/ext/joda-time-2.4-javadoc.jar file.reference.joda-time-2.4-sources.jar=release/modules/ext/joda-time-2.4-sources.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 9f2244cf71..a27c466f87 100644 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -686,8 +686,8 @@ release/modules/ext/poi-ooxml-schemas-3.8.jar - ext/jfxtras-controls-8.0-r1.jar - release/modules/ext/jfxtras-controls-8.0-r1.jar + ext/jfxtras-controls-8.0-r3.jar + release/modules/ext/jfxtras-controls-8.0-r3.jar ext/gson-1.4.jar @@ -714,8 +714,8 @@ release/modules/ext/guava-11.0.2.jar - ext/jfxtras-common-8.0-r1-sources.jar - release/modules/ext/jfxtras-common-8.0-r1-sources.jar + ext/jfxtras-common-8.0-r3-sources.jar + release/modules/ext/jfxtras-common-8.0-r3-sources.jar ext/mail-1.4.3.jar @@ -746,8 +746,8 @@ release/modules/ext/joda-time-2.4-javadoc.jar - ext/jfxtras-fxml-8.0-r1-sources.jar - release/modules/ext/jfxtras-fxml-8.0-r1-sources.jar + ext/jfxtras-fxml-8.0-r3-sources.jar + release/modules/ext/jfxtras-fxml-8.0-r3-sources.jar ext/jcalendarbutton-1.4.6.jar @@ -802,28 +802,28 @@ release/modules/ext/joda-time-2.4.jar - ext/jfxtras-fxml-8.0-r1-javadoc.jar - release/modules/ext/jfxtras-fxml-8.0-r1-javadoc.jar + ext/jfxtras-fxml-8.0-r3-javadoc.jar + release/modules/ext/jfxtras-fxml-8.0-r3-javadoc.jar + + + ext/jfxtras-fxml-8.0-r3.jar + release/modules/ext/jfxtras-fxml-8.0-r3.jar ext/common-io-3.1.1.jar release/modules/ext/common-io-3.1.1.jar - ext/jfxtras-fxml-8.0-r1.jar - release/modules/ext/jfxtras-fxml-8.0-r1.jar - - - ext/jfxtras-common-8.0-r1.jar - release/modules/ext/jfxtras-common-8.0-r1.jar + ext/jfxtras-common-8.0-r3.jar + release/modules/ext/jfxtras-common-8.0-r3.jar ext/commons-logging-1.1.2-javadoc.jar release/modules/ext/commons-logging-1.1.2-javadoc.jar - ext/jfxtras-controls-8.0-r1-javadoc.jar - release/modules/ext/jfxtras-controls-8.0-r1-javadoc.jar + ext/jfxtras-controls-8.0-r3-javadoc.jar + release/modules/ext/jfxtras-controls-8.0-r3-javadoc.jar ext/slf4j-simple-1.6.1.jar @@ -894,8 +894,8 @@ release/modules/ext/commons-lang3-3.0.jar - ext/jfxtras-common-8.0-r1-javadoc.jar - release/modules/ext/jfxtras-common-8.0-r1-javadoc.jar + ext/jfxtras-common-8.0-r3-javadoc.jar + release/modules/ext/jfxtras-common-8.0-r3-javadoc.jar ext/imageio-iff-3.1.1.jar @@ -918,12 +918,12 @@ release/modules/ext/gstreamer-java-1.5.jar - ext/imageio-metadata-3.1.1.jar - release/modules/ext/imageio-metadata-3.1.1.jar + ext/jfxtras-controls-8.0-r3-sources.jar + release/modules/ext/jfxtras-controls-8.0-r3-sources.jar - ext/jfxtras-controls-8.0-r1-sources.jar - release/modules/ext/jfxtras-controls-8.0-r1-sources.jar + ext/imageio-metadata-3.1.1.jar + release/modules/ext/imageio-metadata-3.1.1.jar ext/imageio-pict-3.1.1.jar diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java index 27b3523a26..70ba5d9716 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableDB.java @@ -34,7 +34,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; +import static java.util.Objects.isNull; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; @@ -50,6 +50,7 @@ import org.sleuthkit.autopsy.coreutils.HashHitUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.imagegallery.FileTypeUtils; import org.sleuthkit.autopsy.imagegallery.ImageGalleryController; +import org.sleuthkit.autopsy.imagegallery.ImageGalleryModule; import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupKey; import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupManager; import org.sleuthkit.autopsy.imagegallery.datamodel.grouping.GroupSortBy; @@ -1123,8 +1124,6 @@ public final class DrawableDB { */ @Nonnull public Set getHashSetsForFileFromAutopsy(long fileID) { -// return hashh - return HashHitUtils.getHashSetNamesForFile(tskCase, fileID); } @@ -1193,12 +1192,9 @@ public final class DrawableDB { * returns false if passed a null AbstractFile */ public boolean isVideoFile(AbstractFile f) { - if (Objects.isNull(f)) { - return false; - } else { - return videoFileMap.computeIfAbsent(f.getId(), (id) -> FileTypeUtils.isVideoFile(f)); - } - + return isNull(f) ? false + : videoFileMap.computeIfAbsent(f.getId(), id -> FileTypeUtils.isVideoFile(f)); + } /** diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableFile.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableFile.java index 80519e8b82..cd9335684b 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableFile.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/datamodel/DrawableFile.java @@ -58,32 +58,20 @@ import org.sleuthkit.datamodel.TskCoreException; public abstract class DrawableFile extends AbstractFile { public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed) { - if (FileTypeUtils.isVideoFile(abstractFileById)) { - return new VideoFile<>(abstractFileById, analyzed); - } else { - return new ImageFile<>(abstractFileById, analyzed); - } + return create(abstractFileById, analyzed, FileTypeUtils.isVideoFile(abstractFileById)); } /** * Skip the database query if we have already determined the file type. */ public static DrawableFile create(AbstractFile abstractFileById, boolean analyzed, boolean isVideo) { - if (isVideo) { - return new VideoFile<>(abstractFileById, analyzed); - } else { - return new ImageFile<>(abstractFileById, analyzed); - } + return isVideo + ? new VideoFile<>(abstractFileById, analyzed) + : new ImageFile<>(abstractFileById, analyzed); } public static DrawableFile create(Long id, boolean analyzed) throws TskCoreException, IllegalStateException { - - AbstractFile abstractFileById = Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id); - if (FileTypeUtils.isVideoFile(abstractFileById)) { - return new VideoFile<>(abstractFileById, analyzed); - } else { - return new ImageFile<>(abstractFileById, analyzed); - } + return create(Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id), analyzed); } SoftReference imageRef; @@ -124,7 +112,6 @@ public abstract class DrawableFile extends AbstractFile @Override public T accept(SleuthkitItemVisitor v) { - return file.accept(v); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java index 9461e15ab0..b86e134f3a 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/MetaDataPane.java @@ -21,8 +21,11 @@ package org.sleuthkit.autopsy.imagegallery.gui.drawableviews; import com.google.common.eventbus.Subscribe; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Objects; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; import java.util.Optional; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -30,16 +33,23 @@ import javafx.application.Platform; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.fxml.FXML; +import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.input.Clipboard; +import javafx.scene.input.DataFormat; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.Region; import javafx.scene.text.Text; import javafx.util.Pair; -import org.apache.commons.lang3.StringUtils; import org.sleuthkit.autopsy.events.ContentTagAddedEvent; import org.sleuthkit.autopsy.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.events.TagEvent; @@ -59,14 +69,19 @@ public class MetaDataPane extends DrawableUIBase { private static final Logger LOGGER = Logger.getLogger(MetaDataPane.class.getName()); - @FXML - private TableColumn, ? extends Object>, DrawableAttribute> attributeColumn; + private static final KeyCodeCombination COPY_KEY_COMBINATION = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_DOWN); @FXML - private TableView, ? extends Object>> tableView; + private TableColumn, Collection>, DrawableAttribute> attributeColumn; @FXML - private TableColumn, ? extends Object>, String> valueColumn; + private TableView, Collection>> tableView; + + @FXML + private TableColumn, Collection>, String> valueColumn; + + private final MenuItem copyMenuItem = new MenuItem("Copy"); + private final ContextMenu contextMenu = new ContextMenu(copyMenuItem); public MetaDataPane(ImageGalleryController controller) { super(controller); @@ -74,7 +89,6 @@ public class MetaDataPane extends DrawableUIBase { } @FXML - @SuppressWarnings("unchecked") void initialize() { assert attributeColumn != null : "fx:id=\"attributeColumn\" was not injected: check your FXML file 'MetaDataPane.fxml'."; assert imageView != null : "fx:id=\"imageView\" was not injected: check your FXML file 'MetaDataPane.fxml'."; @@ -83,54 +97,74 @@ public class MetaDataPane extends DrawableUIBase { getController().getTagsManager().registerListener(this); getController().getCategoryManager().registerListener(this); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setPlaceholder(new Label("Select a file to show its details here.")); - - attributeColumn.setCellValueFactory((param) -> new SimpleObjectProperty<>(param.getValue().getKey())); - attributeColumn.setCellFactory((param) -> new TableCell, ? extends Object>, DrawableAttribute>() { - @Override - protected void updateItem(DrawableAttribute item, boolean empty) { - super.updateItem(item, empty); //To change body of generated methods, choose Tools | Templates. - if (item != null) { - setText(item.getDisplayName()); - setGraphic(new ImageView(item.getIcon())); - } else { - setGraphic(null); - setText(null); - } - } - }); - - attributeColumn.setPrefWidth(USE_COMPUTED_SIZE); - - valueColumn.setCellValueFactory((p) -> { - return (p.getValue().getKey() == DrawableAttribute.TAGS) - ? new SimpleStringProperty(((Collection) p.getValue().getValue()).stream() - .map(TagName::getDisplayName) - .filter(Category::isNotCategoryName) - .collect(Collectors.joining(" ; "))) - : new SimpleStringProperty(StringUtils.join((Iterable) p.getValue().getValue(), " ; ")); - }); - valueColumn.setPrefWidth(USE_COMPUTED_SIZE); - valueColumn.setCellFactory((p) -> new TableCell, ? extends Object>, String>() { - @Override - public void updateItem(String item, boolean empty) { - super.updateItem(item, empty); - if (!isEmpty()) { - Text text = new Text(item); - text.wrappingWidthProperty().bind(getTableColumn().widthProperty()); - setGraphic(text); - } else { - setGraphic(null); - } - } - }); - tableView.getColumns().setAll(Arrays.asList(attributeColumn, valueColumn)); - //listen for selection change getController().getSelectionModel().lastSelectedProperty().addListener((observable, oldFileID, newFileID) -> { setFile(newFileID); }); + + copyMenuItem.setAccelerator(COPY_KEY_COMBINATION); + copyMenuItem.setOnAction(actionEvent -> { + copyValueToClipBoard(); + }); + + tableView.setContextMenu(contextMenu); + tableView.setOnKeyPressed((KeyEvent event) -> { + if (COPY_KEY_COMBINATION.match(event)) { + contextMenu.hide(); + copyMenuItem.fire(); + event.consume(); + } + }); + + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setPlaceholder(new Label("Select a file to show its details here.")); + tableView.getColumns().setAll(Arrays.asList(attributeColumn, valueColumn)); + + attributeColumn.setPrefWidth(USE_COMPUTED_SIZE); + attributeColumn.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue().getKey())); + attributeColumn.setCellFactory(param -> new TableCell, Collection>, DrawableAttribute>() { + @Override + protected void updateItem(DrawableAttribute item, boolean empty) { + super.updateItem(item, empty); + if (isNull(item) || empty) { + setGraphic(null); + setText(null); + } else { + setText(item.getDisplayName()); + setGraphic(new ImageView(item.getIcon())); + } + } + }); + + valueColumn.setPrefWidth(USE_COMPUTED_SIZE); + valueColumn.setCellValueFactory(p -> new SimpleStringProperty(getValueDisplayString(p.getValue()))); + valueColumn.setCellFactory(p -> new TableCell, Collection>, String>() { + @Override + public void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + if (isNull(item) || empty) { + setGraphic(null); + } else { + Text text = new Text(item); + text.wrappingWidthProperty().bind(getTableColumn().widthProperty()); + setGraphic(text); + } + } + }); + } + + @SuppressWarnings("unchecked") + static private String getValueDisplayString(Pair, Collection> p) { + if (p.getKey() == DrawableAttribute.TAGS) { + return ((Collection) p.getValue()).stream() + .map(TagName::getDisplayName) + .filter(Category::isNotCategoryName) + .collect(Collectors.joining(" ; ")); + } else { + return p.getValue().stream() + .map(value -> Objects.toString(value, "")) + .collect(Collectors.joining(" ; ")); + } } @Override @@ -158,7 +192,6 @@ public class MetaDataPane extends DrawableUIBase { public void updateUI() { getFile().ifPresent(file -> { final List, Collection>> attributesList = file.getAttributesList(); - Platform.runLater(() -> { tableView.getItems().clear(); tableView.getItems().setAll(attributesList); @@ -207,4 +240,12 @@ public class MetaDataPane extends DrawableUIBase { } }); } + + private void copyValueToClipBoard() { + Pair, Collection> selectedItem = tableView.getSelectionModel().getSelectedItem(); + if (nonNull(selectedItem)) { + Clipboard.getSystemClipboard().setContent(Collections.singletonMap(DataFormat.PLAIN_TEXT, + getValueDisplayString(selectedItem))); + } + } }