From b8f2c693fd210a29db866f87f8781583db6d0105 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 3 Apr 2020 12:40:16 -0400 Subject: [PATCH 01/23] 6161: First steps at implementation --- .../autopsy/geolocation/MapPanel.form | 3 - .../autopsy/geolocation/MapPanel.java | 59 ++++++++++++++++-- .../autopsy/geolocation/MapWaypoint.java | 16 +++++ .../autopsy/images/waypoint_white.png | Bin 0 -> 1243 bytes 4 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/images/waypoint_white.png diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index e915904d42..6a4ab801cd 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -59,7 +59,6 @@ - @@ -87,7 +86,6 @@ - @@ -116,7 +114,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 0462e77842..bc27ecafef 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.geolocation; +import java.awt.AlphaComposite; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -34,9 +36,11 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.function.Function; import java.util.logging.Level; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; @@ -89,7 +93,6 @@ final public class MapPanel extends javax.swing.JPanel { private static final int POPUP_MARGIN = 10; private BufferedImage defaultWaypointImage; - private BufferedImage selectedWaypointImage; private MapWaypoint currentlySelectedWaypoint; @@ -108,8 +111,7 @@ final public class MapPanel extends javax.swing.JPanel { popupFactory = new PopupFactory(); try { - defaultWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_teal.png")); - selectedWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_yellow.png")); + defaultWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_white.png")); } catch (IOException ex) { logger.log(Level.WARNING, "Unable to load geolocation waypoint images", ex); } @@ -685,16 +687,61 @@ final public class MapPanel extends javax.swing.JPanel { * Renderer for the map waypoints. */ private class MapWaypointRenderer implements WaypointRenderer { + private final HashMap imageCache = new HashMap<>(); + + /** + * + * @param waypoint the waypoint for which to get the color + * @param currentlySelectedWaypoint the waypoint that is currently selected + * @return the color that this waypoint should be rendered + */ + private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) { + if (waypoint == currentlySelectedWaypoint) { + return Color.YELLOW; + } + return waypoint.getColor(); + } + + /** + * + * @param baseImg the base image + * @param newColor the color that the resulting image should be changed into + * @return a new waypoint image + */ + private BufferedImage getWaypointImage(BufferedImage baseImg, Color newColor) { + int w = baseImg.getWidth(); + int h = baseImg.getHeight(); + BufferedImage imgOut = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + BufferedImage imgColor = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g = imgColor.createGraphics(); + g.setColor(newColor); + g.fillRect(0, 0, w + 1, h + 1); + g.dispose(); + + Graphics2D graphics = imgOut.createGraphics(); + graphics.drawImage(baseImg, 0, 0, null); + graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN)); + graphics.drawImage(imgColor, 0, 0, null); + graphics.dispose(); + + return imgOut; + } @Override public void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, MapWaypoint waypoint) { + Color color = getColor(waypoint, currentlySelectedWaypoint); + + // Store computed images in cache for later use + BufferedImage image = imageCache.computeIfAbsent(color, k -> { + return getWaypointImage(defaultWaypointImage, color); + }); + Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom()); int x = (int) point.getX(); int y = (int) point.getY(); - - BufferedImage image = (waypoint == currentlySelectedWaypoint ? selectedWaypointImage : defaultWaypointImage); - + (gd.create()).drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null); } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index b327e1c394..14711ac62f 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -18,11 +18,13 @@ */ package org.sleuthkit.autopsy.geolocation; +import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -64,6 +66,12 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private static final Logger logger = Logger.getLogger(MapWaypoint.class.getName()); private final static String HTML_PROP_FORMAT = "%s: %s
"; static private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US); + + private static final HashMap artifactTypesToColors = new HashMap(); + + static { + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); + } private final Waypoint dataModelWaypoint; private final GeoPosition position; @@ -326,6 +334,14 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe return DATE_FORMAT.format(new java.util.Date(timeStamp * 1000)); } + /** + * + * @return the color that this waypoint should be rendered + */ + Color getColor() { + return artifactTypesToColors.getOrDefault(dataModelWaypoint.getArtifact().getArtifactTypeID(), Color.ORANGE); + } + /** * An action class for Extracting artifact files. */ diff --git a/Core/src/org/sleuthkit/autopsy/images/waypoint_white.png b/Core/src/org/sleuthkit/autopsy/images/waypoint_white.png new file mode 100644 index 0000000000000000000000000000000000000000..b3eb5b204f4fbdd7d6ed8687794d86c076aaa135 GIT binary patch literal 1243 zcmeAS@N?(olHy`uVBq!ia0vp^B0#Lf!3HGbSN+@zq!^2X+?^QKos)S9xV%QuQiw3qT4OY$~jP%-qzHM1_jnoV;SI3R@+x3M(KRB&@Hb z09I0xZL1XF8=&BvUzDm~s%N5Spk&9TprBw=l#*r@P?Wt5Z@Sn2DRmzV36 z8|&p4rRy77T3YHG80i}s=>k>g7FXt#Bv$C=6)QswftllyTAW;zSx}OhpQivaH!&%{ zw8U0P31kr*K-^i9nTD__uNdkrpa=CqGWv#k2KsQbfm&@qqE`MznW;dVLFU^T+JIG} zh(YbK(Fa+Mf4GxB z+3m|Um)e)E8OfvAPRhQL|s>j;)Evou>w0&O9oJ*HAdTt!L zm~hx}h9>K&W#`V`eqa6U{JNs^dpy|pegAXreNFxR>MwVy*LhCdE^YF4$`*%NFK_d$ z{O?ue8}m;cj>%T%gm~)i!0n2lay9pAFnCa-4S|;EweL3(et*_S(zDU z(@bajta@7(9saT;YHQTmhHakTQ?^)}6u$Xd)vmBM%=@ZW_2dKtju)IS|7m=&QRVwv z_n%=|>x-j2e63CmWgg;;PyZL(P1<-T&qV5k<|?l9KhlimPCI}0tmfCMzrvw0vlnrf zeGF5YD8RDVV8%`9{^N#woT85C#!Z@c*?+;i`JOyHF%?s{coytG%w?OmJ$lL~*`o&@ zv}W7L@oVWZSDbrTAfYq;_8dQTwRDD%ikltkxn~$Q1nNy!f6DXfR}XW}DeX(A>TgZ? z9`R86(#c!5q)I1m^-*hfve}cr(P_({FJHE7znRm;_{Pbz+N4wX1_urDa_tZnBX@2M7 zhX*x!j`wT6a9w=ScwxiZb?cbe))s7B<9{$hL!@M3!&EQTw$8f~8n^t6t@^a|fP(_V zgZ$isJ0yreIKb= Date: Mon, 6 Apr 2020 09:57:25 -0400 Subject: [PATCH 02/23] changed jgraphx dependency and removed jitpack repository as it prompted for username and password --- Core/ivy.xml | 3 +-- Core/ivysettings.xml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/ivy.xml b/Core/ivy.xml index 5185b58c13..63fdd9ed92 100644 --- a/Core/ivy.xml +++ b/Core/ivy.xml @@ -6,8 +6,7 @@ - - + diff --git a/Core/ivysettings.xml b/Core/ivysettings.xml index c27e095ddb..9c3b496314 100644 --- a/Core/ivysettings.xml +++ b/Core/ivysettings.xml @@ -4,7 +4,6 @@ - From 95611cf4e301464d1e9746d7d075d411741cdd4a Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 12:34:44 -0400 Subject: [PATCH 03/23] 6161 Give different colors to different waypoint types --- .../autopsy/geolocation/MapPanel.java | 80 ++++++++++++------ .../autopsy/geolocation/MapWaypoint.java | 8 +- .../autopsy/images/waypoint_teal.png | Bin 912 -> 0 bytes .../autopsy/images/waypoint_transparent.png | Bin 0 -> 8794 bytes .../autopsy/images/waypoint_white.png | Bin 1243 -> 3435 bytes .../autopsy/images/waypoint_yellow.png | Bin 891 -> 0 bytes 6 files changed, 59 insertions(+), 29 deletions(-) delete mode 100755 Core/src/org/sleuthkit/autopsy/images/waypoint_teal.png create mode 100644 Core/src/org/sleuthkit/autopsy/images/waypoint_transparent.png delete mode 100755 Core/src/org/sleuthkit/autopsy/images/waypoint_yellow.png diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index bc27ecafef..f3ca41c0be 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -40,7 +40,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.function.Function; import java.util.logging.Level; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; @@ -92,7 +91,8 @@ final public class MapPanel extends javax.swing.JPanel { private static final int POPUP_HEIGHT = 200; private static final int POPUP_MARGIN = 10; - private BufferedImage defaultWaypointImage; + private BufferedImage whiteWaypointImage; + private BufferedImage transparentWaypointImage; private MapWaypoint currentlySelectedWaypoint; @@ -111,7 +111,8 @@ final public class MapPanel extends javax.swing.JPanel { popupFactory = new PopupFactory(); try { - defaultWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_white.png")); + whiteWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_white.png")); + transparentWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_transparent.png")); } catch (IOException ex) { logger.log(Level.WARNING, "Unable to load geolocation waypoint images", ex); } @@ -465,7 +466,7 @@ final public class MapPanel extends javax.swing.JPanel { MapWaypoint nextWaypoint = iterator.next(); Point2D point = mapViewer.convertGeoPositionToPoint(nextWaypoint.getPosition()); - Rectangle rect = new Rectangle((int) point.getX() - (defaultWaypointImage.getWidth() / 2), (int) point.getY() - defaultWaypointImage.getHeight(), defaultWaypointImage.getWidth(), defaultWaypointImage.getHeight()); + Rectangle rect = new Rectangle((int) point.getX() - (whiteWaypointImage.getWidth() / 2), (int) point.getY() - whiteWaypointImage.getHeight(), whiteWaypointImage.getWidth(), whiteWaypointImage.getHeight()); if (rect.contains(clickPoint)) { closestPoints.add(nextWaypoint); @@ -689,6 +690,28 @@ final public class MapPanel extends javax.swing.JPanel { private class MapWaypointRenderer implements WaypointRenderer { private final HashMap imageCache = new HashMap<>(); + /** + * + * @param from the color to start with + * @param to the color to blend into + * @param amount the amount by which to blend + * @return a blended color + */ + private Color blend(Color from, Color to, float amount) { + float inverse = 1.0f - amount; + + float fromC[] = new float[3]; + from.getColorComponents(fromC); + float toC[] = new float[3]; + to.getColorComponents(toC); + float afResult[] = new float[3]; + afResult[0] = fromC[0] * inverse + toC[0] * amount; + afResult[1] = fromC[1] * inverse + toC[1] * amount; + afResult[2] = fromC[2] * inverse + toC[2] * amount; + + return new Color (afResult[0], afResult[1], afResult[2]); + } + /** * * @param waypoint the waypoint for which to get the color @@ -696,36 +719,35 @@ final public class MapPanel extends javax.swing.JPanel { * @return the color that this waypoint should be rendered */ private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) { + Color baseColor = waypoint.getColor(); if (waypoint == currentlySelectedWaypoint) { - return Color.YELLOW; + // Highlight this waypoint since it is selected + return blend(baseColor, Color.WHITE, 0.5f); + } else { + return baseColor; } - return waypoint.getColor(); } /** - * - * @param baseImg the base image - * @param newColor the color that the resulting image should be changed into - * @return a new waypoint image + * Creates a waypoint image with the specified color + * @param color the color of the new waypoint image + * @return the new waypoint image */ - private BufferedImage getWaypointImage(BufferedImage baseImg, Color newColor) { - int w = baseImg.getWidth(); - int h = baseImg.getHeight(); - BufferedImage imgOut = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); - BufferedImage imgColor = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + private BufferedImage createWaypointImage(Color color) { + int w = whiteWaypointImage.getWidth(); + int h = whiteWaypointImage.getHeight(); - Graphics2D g = imgColor.createGraphics(); - g.setColor(newColor); - g.fillRect(0, 0, w + 1, h + 1); + BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + + Graphics2D g = ret.createGraphics(); + g.drawImage(whiteWaypointImage, 0,0, null); + g.setComposite(AlphaComposite.SrcIn); + g.setColor(color); + g.fillRect(0,0,w,h); + g.setComposite(AlphaComposite.SrcAtop); + g.drawImage(transparentWaypointImage, 0, 0, null); g.dispose(); - - Graphics2D graphics = imgOut.createGraphics(); - graphics.drawImage(baseImg, 0, 0, null); - graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN)); - graphics.drawImage(imgColor, 0, 0, null); - graphics.dispose(); - - return imgOut; + return ret; } @Override @@ -734,7 +756,7 @@ final public class MapPanel extends javax.swing.JPanel { // Store computed images in cache for later use BufferedImage image = imageCache.computeIfAbsent(color, k -> { - return getWaypointImage(defaultWaypointImage, color); + return createWaypointImage(color); }); Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom()); @@ -742,7 +764,9 @@ final public class MapPanel extends javax.swing.JPanel { int x = (int) point.getX(); int y = (int) point.getY(); - (gd.create()).drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null); + gd = (Graphics2D)gd.create(); + gd.drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null); + gd.dispose(); } } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index 14711ac62f..f53f74af02 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -71,6 +71,12 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe static { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID(), Color.RED); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID(), Color.YELLOW); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID(), Color.GREEN); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID(), Color.ORANGE); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID(), Color.ORANGE); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID(), Color.CYAN); } private final Waypoint dataModelWaypoint; @@ -339,7 +345,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe * @return the color that this waypoint should be rendered */ Color getColor() { - return artifactTypesToColors.getOrDefault(dataModelWaypoint.getArtifact().getArtifactTypeID(), Color.ORANGE); + return artifactTypesToColors.getOrDefault(dataModelWaypoint.getArtifact().getArtifactTypeID(), Color.GRAY); } /** diff --git a/Core/src/org/sleuthkit/autopsy/images/waypoint_teal.png b/Core/src/org/sleuthkit/autopsy/images/waypoint_teal.png deleted file mode 100755 index 3860d1973cc4d86c5a8392953b1699753325a4ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 912 zcmV;B18@9^P)254giDped|VH>fE=Ap7n7czPD)BjKsGfs#qjVj^Yimd zz)heKm=0z97q|`hAvrlYzPh@aEAQlot$$DN4Vs&qnVg(l2txZ5VJL7r;I`ZC8h=OY zGAHqDY5j+F^!D~X0p13#h!q8x2u$YX<;DH;#fcTc6w%8c9igYE=P|HBoQeYU==J(H z(tdKU3Z{ssZ3T>vkKY2a1yFQxu(h>S<1DmC1>AS-7b+?$#MW&Bcsf2lzB23XKvXa# zX(ZFi+}vEJ0Nyg2&6YKn}xN?%xAIS(Z1> zocc@^&`{SzS65d6_^ZWY*{pSar3&~$X(e8-cSr!w=ybY+nImG7qK{xx&I_Pf%w>Cf zyXL}Mxls}Kdj=^hD--i=S1z_!uh-{Bd$AwBDKj=UHVAA{fJwj~vMg&?+niu`7lBQ{ zSg1Md1imXOD$@MfRJWq7n~t{Oa5%(->;asi=AZzIfv(2JM#)_&tS)lw{l-I8Rh1A_ z0`1}KOZj#ZIMmoMVgi@r;ZNL&EnL!vYiDKTKa= z-y9%p@41Ks%mI9DZEez}UBY*tMg7PG`S}4Se-AjjQlQY?G#Cuo$=+|D%UOHiW87}{ zBjA;Au|%$Y0!D&cMLHkAO8=pb@y|@pz>A4KFchG_$a}?+is^r`2jLNlHq>>2wAh zMJ@2t)YQ~tTCJAR(NXb|m8k_5$HvBXOOhlSQUiRh7ARi-t3k-S!CyI5XJ`WM1PMEU m>uM`p2h0F5fB~3T4)_%M&iOpzp8Wj)00005^J%2@zZx>6Vg48bnHo1(xn^X^`&jkXl$umhSFu1ZhFK1z(?w z_u{#F{(;|_^PM?ouIJ)&F_G%3^7uGl8~^}-uc#oS`EP>$g&qszUpK0_ZwCNy&AhdB zT{TTS=p3CLEUawJ>0G@W&FRcNtt9{Hup8J4r-_UEQ_*jtyPp z59ICAZAO2teKdm*JWP<5W=KTm>0yRq?%#=kmeWw&V32tDV#b}z zpKL#y-A6!2zyq;_gwg)4ywDoS@*?`~`|QvA($C`lf=Vwxg0>&W&VNS5K5R)m`$cRD zSLW8|tzT>wA=0aZ@n)E%Y%^$hJe;;6xq&(>k z>1&_ep9 zFy6TfztN#gQpX0{G$4`kz3l>fciCZ|6=X`)ljryjU$d2D<6P@}QTNbu9uZEfLhhyd zBqS=mDY4|vJz~w|v(cEZQ1MC0w1$^hS2xaYn37nsx9Vgzt?2*CQS>>Ao=0}LnD)J5 zh{H}p0@7%2oM^o>>-*iOz3h_T0SUse^2c~&-sO$T zf=;I^o1m0VXdfsHG!lpFeu8kHEy;@u_8gP#IAVpt>tO~6qt^}P)j5f4>NhHHiznLK z!UTG0vz~m21~xuSForT|i;dPVR}&r|py$S*H&wF?v3JufB$;v+Eti2kP~S8nK&xw~ z7+{l^LGG`S!i){b$-4Epj%0V2KESWtu`P=Kha0b2d zkk@c=H5$N5gvf9_?}a|LXQE{W+x*W;)MqoRg<9u%eADMY8*1NMs=YXSlF$!@8VMRq z-&4C}mn1$=a^EhuT%hW)Hs0{b7ctY%lUOsvdz->+kbl^<<i99aIH2>BwO|7=w#h+)9LOni z*~08Pv)^^YFVlI3HIttc%I}=wG~#B1(p-(rn_-H64|^g0DX35ys} z&6dLWVk>?|a~%bNfxEkdRj}A;Oj&#Zu$*Fq|GT#d+}1+g9_+ceTrfgyP=dJ02^`JW zs+d9*=-`whR`-&QpLw)o3WQ$H%QS`DA|~&tb519FO8Vo_3up4f6}v_C@lq~0qXRJ8 zxh?G_LUrW`EKJS1qBUC-vhZn|`cNBbM$Sj8tLYpVIjX#++(Jmfqrq(xVp>;~T9e>% zvJ=F~^^e%Xi((X4@b3ZVLdxS9bPfu?-QEgs9H)i1w{W|Rn9A8xaU?a#VkER+@1unN zQ$~iK4<}sEo;_X#49Tez)ut%NHlk0b%it)c-ymMD2VNQvcOvdxU5!)&c?opb`zU{) z@`&S?o@lZHPH3V|z6g~75P9h^V1Ns9Nhu`9MV51^du?MVvnR61hz}J>AU~G+(yB)! zc+TEZJg3QB#J*cZG)Qi`?$#P=vVJ3@5X~V)B0ZGP3_!o^)m!>jFu#Bo%C8irk{AB! zRhN~BHGWVn0rA2Km2cv=acorT2(P)`2$jJpZDt6TNzYWjWGl^b_NyoKc0V!JHMX&p zLX$VEA-yo=kW7Ej5G9IeZJH#mV^-CMdlJ4(s9EgX2-u}s3PL^-#z4Qemx3R3wB$!0 z;dyD!*SjaRbv_76Y)R){HLgr0&=%rT}f9bUqL z)}~nu@K4`RvAIQBzqEedvZ8oZeEy}3#Hw-S^~3z9+zm%#H22H?S)U%0!wbG(_~>ls zm-I(xpi}wJ#yjasu}l--v6QB{>nC0fTMNOvFln9&*}S)j_zP7BOw1zOG;indUC#Z| zNpbF&MtCd3Z~+_0xh|!#+LUITkutn8%8&HKZqp77l+AKUVXJc8r5wTMdH3?7-exSN zmT8CG&d@|9o=qOO?YT{t9W5h$X}mpDv&3+U*6xgYEzN9ny*~AS}#F zny%Ax#Ycg+Kg`rwr-3`hBCmJTQ*ILXm7m@1=7t&Uj%g?&)%#4*YY;&B9@cHxml%>% z3rQO*m_qNR4B>r!U?7)akY3DX>LQw8=HRp}ivGT-V)hDGWRl8Bp16t!g?e6n;)Bl+ zX{l|hdXsE+Frrn=ERrp*L5J@5SqDa6C`LZ1Pv#e*!gdQ2Vy0&*xe7O*71TJyneGaT zm$6Es0f;rWev%&&7gKL^r}1fK*t$H#`+NG=m*cqAqHPghp~?L9k!zyq>w=C4@i*P3;O<#`@w;GAsGT6mR;?kFoJu z3`QD_7yc@yeB;W1tqsRMPmLWRz6w8g-Iu8iWyCJz0Gb6T+LlWZ;ZK*@2yLzv)rrmN zU$@7bLMOtfL~+m?3Ls=HB!fpJt1d0SPp0$`~@Tr2s&Bz63BW=ek(S-naH z*O(5DA>)UZow1f0f`UEYmFY%c#J^#C4|a9QY8i|mc}kQoE0@ay4n?Y}lc-@@zD+`2 zZqa~jb@Kv4euy5P?u1`3!m@gktkWG&KO*9@?hYNYG9{#4o9UYm#o97@zFG&=rO=4CekOtV@wTf*N#vz2 z+eZ6r5nCFXFbTNirjBA{E}BSD4GC8XjlqO`8NFjNzGNx_q)oL*7)NrEQ&y;?NFox) zDE30Jt8l!Lhxl%wyt#MXUf3{_Wr%M=x%m`ZK)oChpV6?=r@~d ztiB{YxGjEDM9^?lAn$SkiS0+;+>v8Y%iDYHaNTq`4F`~oh5%f`^fyUjm@pSop#vlz1FWx#G z*WKOrw6x8aFh85T_FFO7soz2iAinJh+2*Q?6Udhv_;Pz!DK0vy6#9sQcLqQm0~puw z@B-h7^#&@4)7oDtCy?CHV+9I&^sxa1W7>ibT+jY0W~OwLN6er_E(MJbn?*LO_mwXP z;UWCw`sVIH+`Y`)m$H~3L|Zxu`SMx)B)#a@jGO`JS6$ydJa@3cm>B&=CS)gq;+)(` zgDfqHW7~j!L7BAFN%oHpb=H811u&34@&x#TO|h?(p7Ff*-I`1r2tdtp&KCPO3O$?p z%blkEAtln+-ZU`~J~~sBwYN6|hy0>jH@YcsjO2h5i&XIU8XK2v! zZD_%wX<x!< zolATKKsuHqgU7Cqw*`^=5JkG7T3+tqi3x!{XWfDApyz_Whi8IU^S9CchtJFe>p4kX zpi-QJ?H0t0)@-P+w*^L0e*x8#SHxeZA4Yk-Tp>waTP~i35suTzPF|6P?w3o3D1tfi z`xnnzB!5ko@*0E|={3OODArZn@!)*m&Z2l=At4H}i(~`p)3jiKuMlBp8`gYeKk_g8 z!DfAr`8Fge>rQxr<8|}|@kKq^ZQmquJ_?EgkX0SPDv5dkWH5eV8z|<8LEA-+7Q{t} zu7g6R0JI7usFM<3!iti_UP5sXwpPalOOjZkFiBzx;lBwS{UOqfVjqlYj20cdZ;a7~ za!H70@`^|13yAK60xnPB*ei@3EHBAtbu18izf>e40r9*0DaLPTtl<>}BHyqdXhqOJ z1;XD2Pl;KAGK2iXH+r#@gUV}ps_?VA@RrbTf_s0YIMTO)CxUUeP8>-M30?-TZsDG} z-3hz}N`%9R0tt!0g<%x0@cQtvWeO9}LgK2VqY{*gX|1GM;y>>&@&qX}oT^iR&}HQ* z3yw85zU?xTS@T=dRDeFjhy+>7U+3Ew%4zU^Q?umJ$F>V>l77r*n2tQKbtP&cUXQSs zHhQ-y7gw}t%tZl~!-NK(56GA#a@%l~q(7zWjCqaGS>W-0?KdT@#n8pHrAv(@HU3)b zgBYycua#bMIyRstDvRPB^x7_TdTWRRC-wk&kO_ulb&dZlIn(zP^`*;=ne0#7qB{F@ zhw?|rKbKBr>Xi^-57ux| z#kS(q;;%cb!*7R`hLaLe6K6F&S?pK@SxVbaMRt z{007_Ail6xt3Y}yfnG_&h+CK2;5={}(tikB?$*kDrdI+!=JA`>O^K65=%a!$7g-8t}{D_1o6CBu*vG0%PZkbld8Pq#{?6qS zniDf&CD0c~FOqH)$x2CuL1e9^RwDYuaV)J4oVp(FawyL%T&zxI1pGU9LE7}{48tZP z#1Q~}KG08Vbo-U>cK)kn(WZ*iP@<#TrZ*ubB!-15fR&4bnbWhK#Z>EKf%8^a4`Tdt zR@T?oQFpSv2FKs$>}BnC?N2r>5O$|cYW>ICHjq+C3go4dUddty_hac%R_F=#>f>nD z=!@g7;~yu@^|My{3C@QXZ5N17D6K1O2c-R^H6DY%JM^ve^jgDf<(px}Bb^m4HG3O0 zJ`&nYA2#7m)mH0e4Gyav$fx5cY0PYbhB?;7)VU6cAu-SI6P57x&#fI7gnQ}>1!eeK z`0blK9d_2*w(M4aJkvcqcNB&aav8HqON*4`M>Dr9OfKgT=}^HAm%s4({%^-njS>?FW{ zJ?|P;4l{Y{U?UU66J)ucgwj0hZ+r*t4{;;O2U?)5FAbyHJS&-+%l;;AmawIXaT*=F z9g2DMZ;c#Qx_?yr1U3BCZ130JK3P$7!c>{J@=*P_ifM}>;;^)F05%lybRV)h=ux@N zN^`hhYw`D4KIs-6Jzb-TrKClUc8Gd$UT=&(>fP?YwDpYe*Zre#q_GPv8N8PG^|U5p zD&}l4=htwmc#wn%twQW~nmu2bw4JfsTkVD%$;=kt?;NsBmQzjYyrl}rJ@@r*Irw;J zblX1Vci!tT(Rn>CGZEdn(`k6uewETw*;~V5}BL7q5e~SE1k^d?3KSlnh z$o~}ipCbQL3ew@z~BF={Pwb>e;aH^1wEI4UjZcl6BIyZHpRas zrmLcgEanax2IvL8^{x7M008BeqKuTb!eI4+T12!H_2Bs;uWtYE1_AT$*ZXvJ5S`>i z#>TX9MQ3Lx!jVpDL+YCj`Q5$zGFO|xe#&lL+D|e7AA3q_K}OROb1FGa7OcCE&7*K_EW#~6<_cNt{9eV zd56r>BTmHVKv&81udMY)J`sE2x5OvQ_IXYf){HhVa)7ElMz-l&`4Dqhzl@0C*3~Q00t5F|)K4q@MWtCv(~qr2tEXVnfiQ4gDpn*8?J?%HYp>{5JdE8o3PfGjy z8h)ay1hT-zGb*b3B8upR8cu+_FtPKuXWTT+IgeayhmxvHTy;G-XW|#5@^Tv1Lz;%t?Zjq%_q1Gwuij6rR66rg= z*Jr(VArk-{r%o(Kmxg9e{~-%U+YUi?JD~3uhb5xhQO8!S+P&dw%U*I{W}NIU#$>4C zWkoXT9rZ5+{v;Xdoxn554y(D4BOv;I{xdn;kyXpiB;_ZS7ul~&u|EWb45Yk-7Peph QT>?N+R#gW6&N%4*0Tsvvm;e9( literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/waypoint_white.png b/Core/src/org/sleuthkit/autopsy/images/waypoint_white.png index b3eb5b204f4fbdd7d6ed8687794d86c076aaa135..b3aedebc0642be31f9c1c38615d4cda68bd492b1 100644 GIT binary patch delta 3432 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 Date: Tue, 7 Apr 2020 14:06:26 -0400 Subject: [PATCH 04/23] 6161: Making codacy happy --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 5 +++-- Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index f3ca41c0be..19ae2af47a 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -39,6 +39,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.prefs.PreferenceChangeEvent; @@ -688,7 +689,7 @@ final public class MapPanel extends javax.swing.JPanel { * Renderer for the map waypoints. */ private class MapWaypointRenderer implements WaypointRenderer { - private final HashMap imageCache = new HashMap<>(); + private final Map imageCache = new HashMap<>(); /** * @@ -720,7 +721,7 @@ final public class MapPanel extends javax.swing.JPanel { */ private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) { Color baseColor = waypoint.getColor(); - if (waypoint == currentlySelectedWaypoint) { + if (waypoint.equals(currentlySelectedWaypoint)) { // Highlight this waypoint since it is selected return blend(baseColor, Color.WHITE, 0.5f); } else { diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index f53f74af02..a7590eea11 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import javax.swing.AbstractAction; @@ -67,7 +68,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private final static String HTML_PROP_FORMAT = "%s: %s
"; static private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US); - private static final HashMap artifactTypesToColors = new HashMap(); + private static final Map artifactTypesToColors = new HashMap(); static { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); From 5937c8a8366a03aed83fc9c6f5656a4ba382b539 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 14:17:35 -0400 Subject: [PATCH 05/23] 6248: Fixed the geoloc zoom slider snap bug --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 4 +--- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index e915904d42..31527a830c 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -56,10 +56,10 @@ + - @@ -87,7 +87,6 @@ - @@ -116,7 +115,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 0462e77842..eefa0d5aae 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -310,7 +310,7 @@ final public class MapPanel extends javax.swing.JPanel { void setZoom(int zoom) { zoomChanging = true; mapViewer.setZoom(zoom); - zoomSlider.setValue((zoomSlider.getMaximum() + zoomSlider.getMinimum()) - zoom); + zoomSlider.setValue(zoom); zoomChanging = false; } @@ -572,8 +572,8 @@ final public class MapPanel extends javax.swing.JPanel { zoomSlider.setOrientation(javax.swing.JSlider.VERTICAL); zoomSlider.setPaintTicks(true); zoomSlider.setSnapToTicks(true); + zoomSlider.setInverted(true); zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100)); - zoomSlider.setOpaque(false); zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190)); zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { @@ -591,7 +591,6 @@ final public class MapPanel extends javax.swing.JPanel { zoomInBtn.setBorderPainted(false); zoomInBtn.setFocusPainted(false); zoomInBtn.setRequestFocusEnabled(false); - zoomInBtn.setRolloverEnabled(false); zoomInBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInBtnActionPerformed(evt); @@ -608,7 +607,6 @@ final public class MapPanel extends javax.swing.JPanel { zoomOutBtn.setBorderPainted(false); zoomOutBtn.setFocusPainted(false); zoomOutBtn.setRequestFocusEnabled(false); - zoomOutBtn.setRolloverEnabled(false); zoomOutBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutBtnActionPerformed(evt); From cbc8da324f8ce750675042a10a44e629ba5e759e Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 15:37:48 -0400 Subject: [PATCH 06/23] 6161 Restoring form --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index 6a4ab801cd..3ea3acf6dd 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -59,6 +59,9 @@ + + + @@ -86,6 +89,9 @@ + + + @@ -114,6 +120,9 @@ + + + From 0a5e98aa30f7bcfaf014ea97b6309931575b0bd3 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 15:38:57 -0400 Subject: [PATCH 07/23] 6248: Restoring ui settings --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 9 +++++++++ Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 3 +++ 2 files changed, 12 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index 31527a830c..1287c964c1 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -60,6 +60,9 @@ + + + @@ -87,6 +90,9 @@ + + + @@ -115,6 +121,9 @@ + + + diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index eefa0d5aae..00ef520934 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -574,6 +574,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomSlider.setSnapToTicks(true); zoomSlider.setInverted(true); zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100)); + zoomSlider.setOpaque(false); zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190)); zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { @@ -591,6 +592,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomInBtn.setBorderPainted(false); zoomInBtn.setFocusPainted(false); zoomInBtn.setRequestFocusEnabled(false); + zoomInBtn.setRolloverEnabled(false); zoomInBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInBtnActionPerformed(evt); @@ -607,6 +609,7 @@ final public class MapPanel extends javax.swing.JPanel { zoomOutBtn.setBorderPainted(false); zoomOutBtn.setFocusPainted(false); zoomOutBtn.setRequestFocusEnabled(false); + zoomOutBtn.setRolloverEnabled(false); zoomOutBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutBtnActionPerformed(evt); From 5c3443cdec5066b2dc57d5a09348570ebc8cf01f Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 16:30:38 -0400 Subject: [PATCH 08/23] 6161 Restored form, boosted selection brightness for now --- .../org/sleuthkit/autopsy/geolocation/MapPanel.form | 12 +++--------- .../org/sleuthkit/autopsy/geolocation/MapPanel.java | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) mode change 100755 => 100644 Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form old mode 100755 new mode 100644 index 3ea3acf6dd..e915904d42 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -59,9 +59,7 @@ - - - + @@ -89,9 +87,7 @@ - - - + @@ -120,9 +116,7 @@ - - - + diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 19ae2af47a..de16a04623 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -723,7 +723,7 @@ final public class MapPanel extends javax.swing.JPanel { Color baseColor = waypoint.getColor(); if (waypoint.equals(currentlySelectedWaypoint)) { // Highlight this waypoint since it is selected - return blend(baseColor, Color.WHITE, 0.5f); + return blend(baseColor, Color.WHITE, 0.8f); } else { return baseColor; } From 6ef470b2aefe276225841f8c55824f7da2b3a1c3 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 17:10:39 -0400 Subject: [PATCH 09/23] 6161: Addressing PR comments --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form | 0 Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form old mode 100644 new mode 100755 diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index a7590eea11..ecde4250fb 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -68,8 +68,9 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private final static String HTML_PROP_FORMAT = "%s: %s
"; static private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US); - private static final Map artifactTypesToColors = new HashMap(); + private static final Map artifactTypesToColors = new HashMap<>(); + @SuppressWarnings("deprecation") static { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID(), Color.RED); From 0335b5a84410bf742daf38dd590a4c89e1d2da6f Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Tue, 7 Apr 2020 17:11:59 -0400 Subject: [PATCH 10/23] 6161: Formatted files --- .../autopsy/geolocation/MapPanel.java | 21 +++++++++++-------- .../autopsy/geolocation/MapWaypoint.java | 20 ++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index de16a04623..b2b8589583 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -362,7 +362,7 @@ final public class MapPanel extends javax.swing.JPanel { * Show the popup menu for the given waypoint and location. * * @param waypoint Selected waypoint - * @param point Current mouse click location + * @param point Current mouse click location */ private void showPopupMenu(MapWaypoint waypoint, Point point) throws TskCoreException { if (waypoint == null) { @@ -441,7 +441,7 @@ final public class MapPanel extends javax.swing.JPanel { * @param clickPoint The mouse click point * * @return A waypoint that is within 10 pixels of the given point, or null - * if none was found. + * if none was found. */ private List findClosestWaypoint(Point clickPoint) { if (waypointTree == null) { @@ -689,6 +689,7 @@ final public class MapPanel extends javax.swing.JPanel { * Renderer for the map waypoints. */ private class MapWaypointRenderer implements WaypointRenderer { + private final Map imageCache = new HashMap<>(); /** @@ -710,13 +711,14 @@ final public class MapPanel extends javax.swing.JPanel { afResult[1] = fromC[1] * inverse + toC[1] * amount; afResult[2] = fromC[2] * inverse + toC[2] * amount; - return new Color (afResult[0], afResult[1], afResult[2]); + return new Color(afResult[0], afResult[1], afResult[2]); } /** - * + * * @param waypoint the waypoint for which to get the color - * @param currentlySelectedWaypoint the waypoint that is currently selected + * @param currentlySelectedWaypoint the waypoint that is currently + * selected * @return the color that this waypoint should be rendered */ private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) { @@ -731,6 +733,7 @@ final public class MapPanel extends javax.swing.JPanel { /** * Creates a waypoint image with the specified color + * * @param color the color of the new waypoint image * @return the new waypoint image */ @@ -741,10 +744,10 @@ final public class MapPanel extends javax.swing.JPanel { BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g = ret.createGraphics(); - g.drawImage(whiteWaypointImage, 0,0, null); + g.drawImage(whiteWaypointImage, 0, 0, null); g.setComposite(AlphaComposite.SrcIn); g.setColor(color); - g.fillRect(0,0,w,h); + g.fillRect(0, 0, w, h); g.setComposite(AlphaComposite.SrcAtop); g.drawImage(transparentWaypointImage, 0, 0, null); g.dispose(); @@ -764,8 +767,8 @@ final public class MapPanel extends javax.swing.JPanel { int x = (int) point.getX(); int y = (int) point.getY(); - - gd = (Graphics2D)gd.create(); + + gd = (Graphics2D) gd.create(); gd.drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null); gd.dispose(); } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index ecde4250fb..07131d5c00 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -67,11 +67,13 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private static final Logger logger = Logger.getLogger(MapWaypoint.class.getName()); private final static String HTML_PROP_FORMAT = "%s: %s
"; static private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US); - + private static final Map artifactTypesToColors = new HashMap<>(); - + @SuppressWarnings("deprecation") - static { + static + + { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID(), Color.RED); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID(), Color.YELLOW); @@ -91,7 +93,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe * @param dmWaypoints * * @return List of MapWaypoint objects. List will be empty if dmWaypoints - * was empty or null. + * was empty or null. */ static Set getWaypoints(List dmWaypoints) { Set mapPoints = new LinkedHashSet<>(); @@ -113,7 +115,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe * @param mapWaypoints * * @return A list of Waypoint objects, or empty list if mapWaypoints was - * null or empty. + * null or empty. */ static List getDataModelWaypoints(List mapWaypoints) { List waypoints = new ArrayList<>(); @@ -199,7 +201,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe String getHTMLFormattedWaypointDetails() { return getFormattedDetails(dataModelWaypoint); } - + /** * Returns a list of JMenuItems for the waypoint. The list list may contain * nulls which should be removed or replaced with JSeparators. @@ -248,7 +250,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe * menu items can be put in a consistent order with other parts of the UI. * * @param artifact Artifact for the selected waypoint - * @param content Artifact content + * @param content Artifact content * * @return List of JMenuItems for the DataModelActionFactory actions */ @@ -284,7 +286,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe /** * Get the nicely formatted details for the given waypoint. * - * @param point Waypoint object + * @param point Waypoint object * @param header String details header * * @return HTML formatted String of details for given waypoint @@ -343,7 +345,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe } /** - * + * * @return the color that this waypoint should be rendered */ Color getColor() { From 32c67382cca734993cddfc1d05ea410eea600db7 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Wed, 8 Apr 2020 10:31:57 -0400 Subject: [PATCH 11/23] 6161: Fixing build --- .../org/sleuthkit/autopsy/geolocation/MapPanel.java | 10 +++++----- .../org/sleuthkit/autopsy/geolocation/MapWaypoint.java | 5 +---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index b2b8589583..26caf30654 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -706,12 +706,12 @@ final public class MapPanel extends javax.swing.JPanel { from.getColorComponents(fromC); float toC[] = new float[3]; to.getColorComponents(toC); - float afResult[] = new float[3]; - afResult[0] = fromC[0] * inverse + toC[0] * amount; - afResult[1] = fromC[1] * inverse + toC[1] * amount; - afResult[2] = fromC[2] * inverse + toC[2] * amount; + float result[] = new float[3]; + result[0] = fromC[0] * inverse + toC[0] * amount; + result[1] = fromC[1] * inverse + toC[1] * amount; + result[2] = fromC[2] * inverse + toC[2] * amount; - return new Color(afResult[0], afResult[1], afResult[2]); + return new Color(result[0], result[1], result[2]); } /** diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index 07131d5c00..48a0593a95 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -70,10 +70,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe private static final Map artifactTypesToColors = new HashMap<>(); - @SuppressWarnings("deprecation") - static - - { + static { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID(), Color.RED); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID(), Color.YELLOW); From 7290c20d8551536bf82536d32a3aa26fbabb3d17 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Wed, 8 Apr 2020 10:39:53 -0400 Subject: [PATCH 12/23] 6248: Restoring form --- .../org/sleuthkit/autopsy/geolocation/MapPanel.form | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form index 1287c964c1..e915904d42 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.form @@ -56,13 +56,10 @@ - - - - + @@ -90,9 +87,7 @@ - - - + @@ -121,9 +116,7 @@ - - - + From 532f3063c7f72c45dda006a6d34ac27014eabc63 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 11:23:56 -0400 Subject: [PATCH 13/23] Update to openjdk in docs --- docs/doxygen-user/images/serviceinstall.PNG | Bin 20955 -> 31708 bytes docs/doxygen-user/images/wherejava.PNG | Bin 1017 -> 9711 bytes .../multi-user/installActiveMQ.dox | 4 ++-- docs/doxygen-user/multi-user/installSolr.dox | 10 +++++++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/doxygen-user/images/serviceinstall.PNG b/docs/doxygen-user/images/serviceinstall.PNG index 3a5ea81b47a43f409df7b3b3410e481d932c18c8..b20f07d9c8b25329b3e384956eb61af3af5dbf0b 100644 GIT binary patch literal 31708 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 QQe@G;VRF4#+cE6_05c+Pn*aa+ literal 20955 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 literal 1017 zcmeAS@N?(olHy`uVBq!ia0y~yUl}w0VAYX5{?}w0$<9pMbGwb~;L?@wFzD*JBq$(VIjJL<~k z+O^en_tLj6t38|HZydOOQSt8YKla%EzO^dvnNNM`wbj2u{eNev7SEi^dTZsojq}96 zny%h^GBW$y8p*}B_22AkmnB!OKjpgD`O5WM?{=Ot0T=;W$T_=G4+hzHgpq zo1NSGZ1c@`_g3Vail)}+ZZe8a-J`QUJ^ph|d~x7;7s=I;wpC$uap`3*?!2>|_PzLD zWvF@aw)zuBQSoP8w`x2t{p%h3v3|j-Szk@pzsk=4KIiJDxKfZyH_v)s6u5u($FNPa zD!)eh{<`XO^>bLU*YmRX8~@C-=DU05=DyCNsBWXk*zCZxrRCkpjdJ|I4qohz@O>?K zwzN1jz8V;8aaX=?T@ya{umAj)Yo6_n0eRcSPS%$Md7VmqPX!asM{SmE z%+>P|$DY5vdCpGy;?EazuFgB8f8qbsf1l#Moj&6I=ga>6wfB8Yn!EQLX0rXz|1ACS v`~K+_(}9WG|2WR%PDGBtP~u}__n%3p?OnHCoLCt!yE1sX`njxgN@xNAh6?w< diff --git a/docs/doxygen-user/multi-user/installActiveMQ.dox b/docs/doxygen-user/multi-user/installActiveMQ.dox index 4d7ab37fe5..475e558a08 100644 --- a/docs/doxygen-user/multi-user/installActiveMQ.dox +++ b/docs/doxygen-user/multi-user/installActiveMQ.dox @@ -8,14 +8,14 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w \section install_activemq_prereq Prerequisites You will need: -- 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html. +- 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. - Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0. \section install_activemq_install Installation \subsection install_activemq_install_java JRE Installation -Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output like the yellow results below, you have a JRE. +Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE.

\image html wherejava.PNG

diff --git a/docs/doxygen-user/multi-user/installSolr.dox b/docs/doxygen-user/multi-user/installSolr.dox index 3d55f29efc..f49c2e4b39 100644 --- a/docs/doxygen-user/multi-user/installSolr.dox +++ b/docs/doxygen-user/multi-user/installSolr.dox @@ -13,7 +13,7 @@ Solr's embedded ZooKeeper is also used as a coordination service for Autopsy. We use Bitnami Solr, which packages Solr as a Windows service. You will need: -- A 64-bit version of the Java Runtime Environment (JRE) from http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html. +- A 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. - The Apache Solr 4.10.3-0 installation package. This is no longer available from its original source, but you can find it on our site: https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr. -- NOTE: We tested Solr 6 at one point, but ran into stability problems when loading and unloading cores. For now, you need to use Solr 4. - An installed version of Autopsy so that you can copy files from it. You can install Autopsy on one of the planned client systems. You do not need to install it on the Solr server. @@ -24,7 +24,11 @@ You will need: \section install_solr_install Installation \subsection install_solr_install_java JRE Installation -1. JREs are normally installed under "C:\Program Files\Java\jre(version)", so check there to see if you have one installed already. If not, get the installer as listed in the above Prerequisites section and install it with the default settings. +1. Install the Java JRE if needed. You can test this by running _where java_ from the command line. If you see output similar to the results below, you have a JRE. +

+\image html wherejava.PNG +

+If you need the JRE, install it with the default settings. \subsection install_solr_install_solr Solr Installation @@ -52,7 +56,7 @@ The following steps will configure Solr to run using an account that will have a + ++JvmOptions=-Dbootstrap_confdir="C:\Bitnami\solr-4.10.3-0\apache-solr\solr\configsets\AutopsyConfig\conf" + ++JvmOptions=-DzkRun
- - Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: –-JavaHome="C:\Program Files\Java\jre1.8.0_111" + - Replace the path to JavaHome with the path to your 64-bit version of the JRE. If you do not know the path, the correct JavaHome path can be obtained by running the command "where java" from the Windows command line. An example is shown below. The text in yellow is what we are interested in. Do not include the "bin" folder in the path you place into the JavaHome variable. A correct example of the final result will look something like this: –-JavaHome="C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1"

A portion of an updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.

From b7b6d95636bb17bbf8f2ac4b51a178f392613730 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 14:23:51 -0400 Subject: [PATCH 14/23] Updated release notes for 4.15 --- NEWS.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/NEWS.txt b/NEWS.txt index ee294d7fea..068408b413 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,32 @@ +---------------- VERSION 4.15.0 -------------- +New UI Features: +- Added Document view to File Discovery. +- Expanded Context Content Viewer to show if an app accessed a file. +- Added translation feature to Message Content Viewer. +- Added waypoint type filter to the Geolocation viewer. +- Added zoom feature to Indexed Text Content Viewer. + +New Ingest Modules Features: +- New GPX ingest module. +- New Drone ingest module for DJI drones based on DatCon. +- Create artifacts for files opened by Adobe Reader, Windows Media Player, Office Docs (Most Recently Used (MRU) and TrustRecords), 7Zip MRU, WinRAR MRU, Applets, Microsoft Management Console (MMC) via RegRipper. + +New Central Repository Features: +- Central Repository stores account IDs that were previously seen. +- Central Repository is enabled by default to store past hashes. Feature to flag previously seen files is disabled by default. + +Other New Features: +- Multi-user cases can be created via command line + +Bug fixes: +- Prevent entire application from crashing when gstreamer crashes on videos. +- Improve Geolocation viewer with large data sets. +- Fix error with non-sector aligned reads on local disks. +- Times from Recycle Bin files are now in timeline. +- Validate timeline events and ignore events too far in the future. +- Moved some database queries off of UI thread. +- Remove hard coded sizes from UI that cause issues with other languages. + ---------------- VERSION 4.14.0 -------------- Specialized UIs: - New File Discovery UI that allows you to search and filter for certain types of files. From 15d00d38c90aba157c09f569ccc625da6b5f894d Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 8 Apr 2020 14:34:31 -0400 Subject: [PATCH 15/23] Fix doxygen warning --- .../centralrepository/datamodel/CorrelationAttributeUtil.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 71c6b41f86..5cbc3307a0 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -201,11 +201,9 @@ public class CorrelationAttributeUtil { * Makes a correlation attribute instance from a phone number attribute of an * artifact. * + * @param corrAttrInstances Correlation attributes will be added to this. * @param artifact An artifact with a phone number attribute. * - * @return The correlation instance artifact or null, if the phone number is - * not a valid correlation attribute. - * * @throws TskCoreException If there is an error querying the case * database. * @throws CentralRepoException If there is an error querying the central From d5ed936797523f6521d6d143a5a12cbaa3729a7d Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Apr 2020 19:08:35 -0400 Subject: [PATCH 16/23] Release 4.15.0 version number changes --- Core/manifest.mf | 2 +- Core/nbproject/project.properties | 2 +- Core/nbproject/project.xml | 2 +- CoreLibs/manifest.mf | 4 ++-- Experimental/nbproject/project.xml | 4 ++-- ImageGallery/nbproject/project.xml | 4 ++-- KeywordSearch/nbproject/project.xml | 4 ++-- RecentActivity/nbproject/project.xml | 4 ++-- Testing/nbproject/project.xml | 2 +- docs/doxygen-user/Doxyfile | 4 ++-- docs/doxygen/Doxyfile | 4 ++-- nbproject/project.properties | 6 +++--- thunderbirdparser/nbproject/project.xml | 2 +- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Core/manifest.mf b/Core/manifest.mf index 494ba39afc..00681f3e7f 100644 --- a/Core/manifest.mf +++ b/Core/manifest.mf @@ -2,7 +2,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.core/10 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml -OpenIDE-Module-Implementation-Version: 30 +OpenIDE-Module-Implementation-Version: 31 OpenIDE-Module-Requires: org.openide.windows.WindowManager AutoUpdate-Show-In-Client: true AutoUpdate-Essential-Module: true diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index c7ceb01a4a..3fd1ed05d9 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -126,5 +126,5 @@ nbm.homepage=http://www.sleuthkit.org/ nbm.module.author=Brian Carrier nbm.needs.restart=true source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar -spec.version.base=10.18 +spec.version.base=10.19 diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 4aa97960f3..64d9509e59 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -251,7 +251,7 @@ 3 - 1.3 + 1.4
diff --git a/CoreLibs/manifest.mf b/CoreLibs/manifest.mf index 1f7fcc545e..95267126df 100644 --- a/CoreLibs/manifest.mf +++ b/CoreLibs/manifest.mf @@ -1,8 +1,8 @@ Manifest-Version: 1.0 OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3 -OpenIDE-Module-Implementation-Version: 6 +OpenIDE-Module-Implementation-Version: 7 OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties -OpenIDE-Module-Specification-Version: 1.3 +OpenIDE-Module-Specification-Version: 1.4 AutoUpdate-Show-In-Client: true AutoUpdate-Essential-Module: true diff --git a/Experimental/nbproject/project.xml b/Experimental/nbproject/project.xml index 90fbce3d76..166c73f0a5 100644 --- a/Experimental/nbproject/project.xml +++ b/Experimental/nbproject/project.xml @@ -135,7 +135,7 @@ 10 - 10.18 + 10.19
@@ -144,7 +144,7 @@ 3 - 1.3 + 1.4 diff --git a/ImageGallery/nbproject/project.xml b/ImageGallery/nbproject/project.xml index a7157df475..4ef4c1fde1 100644 --- a/ImageGallery/nbproject/project.xml +++ b/ImageGallery/nbproject/project.xml @@ -127,7 +127,7 @@ 10 - 10.18 + 10.19 @@ -136,7 +136,7 @@ 3 - 1.3 + 1.4 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 2de991d105..10e1e76bfe 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -119,7 +119,7 @@ 10 - 10.18 + 10.19
@@ -128,7 +128,7 @@ 3 - 1.3 + 1.4 diff --git a/RecentActivity/nbproject/project.xml b/RecentActivity/nbproject/project.xml index 89394f1b1f..f6465f00a5 100644 --- a/RecentActivity/nbproject/project.xml +++ b/RecentActivity/nbproject/project.xml @@ -60,7 +60,7 @@ 10 - 10.18 + 10.19
@@ -69,7 +69,7 @@ 3 - 1.3 + 1.4 diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml index def60a06ac..2ebb94a835 100644 --- a/Testing/nbproject/project.xml +++ b/Testing/nbproject/project.xml @@ -47,7 +47,7 @@ 10 - 10.18 + 10.19 diff --git a/docs/doxygen-user/Doxyfile b/docs/doxygen-user/Doxyfile index 6eb71ae8f8..0f985042a3 100644 --- a/docs/doxygen-user/Doxyfile +++ b/docs/doxygen-user/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy User Documentation" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.14.0 +PROJECT_NUMBER = 4.15.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -1025,7 +1025,7 @@ GENERATE_HTML = YES # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = 4.14.0 +HTML_OUTPUT = 4.15.0 # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 6490edacd6..993ee8ded2 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Autopsy" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.14.0 +PROJECT_NUMBER = 4.15.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears a the top of each page and should give viewer a @@ -1066,7 +1066,7 @@ GENERATE_HTML = YES # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_OUTPUT = api-docs/4.14.0/ +HTML_OUTPUT = api-docs/4.15.0/ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). diff --git a/nbproject/project.properties b/nbproject/project.properties index 1f61a9c967..7cb61fc13a 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -4,10 +4,10 @@ app.title=Autopsy ### lowercase version of above app.name=${branding.token} ### if left unset, version will default to today's date -app.version=4.14.0 +app.version=4.15.0 ### build.type must be one of: DEVELOPMENT, RELEASE -#build.type=RELEASE -build.type=DEVELOPMENT +build.type=RELEASE +#build.type=DEVELOPMENT project.org.netbeans.progress=org-netbeans-api-progress project.org.sleuthkit.autopsy.experimental=Experimental diff --git a/thunderbirdparser/nbproject/project.xml b/thunderbirdparser/nbproject/project.xml index 4eebb3d2f4..29782066ac 100644 --- a/thunderbirdparser/nbproject/project.xml +++ b/thunderbirdparser/nbproject/project.xml @@ -36,7 +36,7 @@ 10 - 10.18 + 10.19 From 72a350debf688c5d768bb62e1e2809c8baa05835 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Apr 2020 20:42:07 -0400 Subject: [PATCH 17/23] Toggle build to DEVELOPMENT --- nbproject/project.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nbproject/project.properties b/nbproject/project.properties index 7cb61fc13a..390228bc4d 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -6,8 +6,8 @@ app.name=${branding.token} ### if left unset, version will default to today's date app.version=4.15.0 ### build.type must be one of: DEVELOPMENT, RELEASE -build.type=RELEASE -#build.type=DEVELOPMENT +#build.type=RELEASE +build.type=DEVELOPMENT project.org.netbeans.progress=org-netbeans-api-progress project.org.sleuthkit.autopsy.experimental=Experimental From 6ff3be941e3cd41229d94cd7ee36d8b1766181d6 Mon Sep 17 00:00:00 2001 From: apriestman Date: Thu, 9 Apr 2020 11:00:53 -0400 Subject: [PATCH 18/23] Specify Java 8 and add installer links. --- docs/doxygen-user/multi-user/installActiveMQ.dox | 2 +- docs/doxygen-user/multi-user/installSolr.dox | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doxygen-user/multi-user/installActiveMQ.dox b/docs/doxygen-user/multi-user/installActiveMQ.dox index 475e558a08..07a6f1dcfd 100644 --- a/docs/doxygen-user/multi-user/installActiveMQ.dox +++ b/docs/doxygen-user/multi-user/installActiveMQ.dox @@ -8,7 +8,7 @@ ActiveMQ is a messaging service that allows the Autopsy clients to communicate w \section install_activemq_prereq Prerequisites You will need: -- 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. +- 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild ( Link to installer) - Download ActiveMQ from: http://activemq.apache.org/download.html . Autopsy has been tested with ActiveMQ version 5.14.0. diff --git a/docs/doxygen-user/multi-user/installSolr.dox b/docs/doxygen-user/multi-user/installSolr.dox index f49c2e4b39..1c3970e344 100644 --- a/docs/doxygen-user/multi-user/installSolr.dox +++ b/docs/doxygen-user/multi-user/installSolr.dox @@ -13,7 +13,7 @@ Solr's embedded ZooKeeper is also used as a coordination service for Autopsy. We use Bitnami Solr, which packages Solr as a Windows service. You will need: -- A 64-bit version of the Java Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. +- A 64-bit version of the Java 8 Runtime Environment (JRE) from https://github.com/ojdkbuild/ojdkbuild. ( Link to installer) - The Apache Solr 4.10.3-0 installation package. This is no longer available from its original source, but you can find it on our site: https://sourceforge.net/projects/autopsy/files/CollaborativeServices/Solr. -- NOTE: We tested Solr 6 at one point, but ran into stability problems when loading and unloading cores. For now, you need to use Solr 4. - An installed version of Autopsy so that you can copy files from it. You can install Autopsy on one of the planned client systems. You do not need to install it on the Solr server. From 8a71c6e9f90e05ac11b7cd7c1d5fd265f4081717 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 9 Apr 2020 15:02:12 -0400 Subject: [PATCH 19/23] update for wrapped jars --- Core/nbproject/project.properties | 2 +- Core/nbproject/project.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index c7ceb01a4a..b34db751e1 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -42,7 +42,7 @@ file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar file.reference.jdom2-2.0.6.jar=release\\modules\\ext\\jdom2-2.0.6.jar file.reference.jempbox-1.8.16.jar=release\\modules\\ext\\jempbox-1.8.16.jar file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar -file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar +file.reference.jgraphx-4.1.0.jar=release/modules/ext/jgraphx-4.1.0.jar file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 4aa97960f3..d05ee534d9 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -495,6 +495,10 @@ ext/vorbis-java-core-0.8.jar release\modules\ext\vorbis-java-core-0.8.jar + + ext/jgraphx-4.1.0.jar + release/modules/ext/jgraphx-4.1.0.jar + ext/java-libpst-0.8.1.jar release\modules\ext\java-libpst-0.8.1.jar @@ -711,10 +715,6 @@ ext/google-auth-library-oauth2-http-0.15.0.jar release/modules/ext/google-auth-library-oauth2-http-0.15.0.jar - - ext/jgraphx-v3.8.0.jar - release/modules/ext/jgraphx-v3.8.0.jar - ext/juniversalchardet-1.0.3.jar release\modules\ext\juniversalchardet-1.0.3.jar From 3a110c2849cfcd72cab0dd693429d8bd65b5e00b Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 10 Apr 2020 09:57:41 -0400 Subject: [PATCH 20/23] 6161: Highlight color -> white --- .../autopsy/geolocation/MapPanel.java | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 26caf30654..430d2e58f5 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -692,28 +692,6 @@ final public class MapPanel extends javax.swing.JPanel { private final Map imageCache = new HashMap<>(); - /** - * - * @param from the color to start with - * @param to the color to blend into - * @param amount the amount by which to blend - * @return a blended color - */ - private Color blend(Color from, Color to, float amount) { - float inverse = 1.0f - amount; - - float fromC[] = new float[3]; - from.getColorComponents(fromC); - float toC[] = new float[3]; - to.getColorComponents(toC); - float result[] = new float[3]; - result[0] = fromC[0] * inverse + toC[0] * amount; - result[1] = fromC[1] * inverse + toC[1] * amount; - result[2] = fromC[2] * inverse + toC[2] * amount; - - return new Color(result[0], result[1], result[2]); - } - /** * * @param waypoint the waypoint for which to get the color @@ -725,7 +703,7 @@ final public class MapPanel extends javax.swing.JPanel { Color baseColor = waypoint.getColor(); if (waypoint.equals(currentlySelectedWaypoint)) { // Highlight this waypoint since it is selected - return blend(baseColor, Color.WHITE, 0.8f); + return Color.WHITE; } else { return baseColor; } From f43e375891685d47f292cbe05ff9f7d3a9a19124 Mon Sep 17 00:00:00 2001 From: apriestman Date: Fri, 10 Apr 2020 11:03:29 -0400 Subject: [PATCH 21/23] Change variable name --- InternalPythonModules/GPX_Module/GPX_Parser_Module.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py index fe92d0d659..3d202a963b 100644 --- a/InternalPythonModules/GPX_Module/GPX_Parser_Module.py +++ b/InternalPythonModules/GPX_Module/GPX_Parser_Module.py @@ -214,10 +214,10 @@ class GPXParserDataSourceIngestModule(DataSourceIngestModule): geoWaypoints = GeoWaypoints() for point in route.points: - geoWaypointList.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) + geoWaypoints.addPoint(Waypoint(point.latitude, point.longitude, point.elevation, point.name)) try: - geoArtifactHelper.addRoute(None, None, geoWaypointList, None) + geoArtifactHelper.addRoute(None, None, geoWaypoints, None) except Blackboard.BlackboardException as e: self.log("Error posting GPS route artifact for " + file.getUniquePath() + " (objID = " + str(file.getId()) + "):" + e.getMessage()) except TskCoreException as e: From e44251ce0b44499e8ee08f09b4bb23f962930530 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 10 Apr 2020 12:30:10 -0400 Subject: [PATCH 22/23] 6161: Icons are now the color of their waypoint rather than the artifact type icon --- .../autopsy/geolocation/GeoFilterPanel.java | 70 ++++++++++++------- .../autopsy/geolocation/MapWaypoint.java | 10 ++- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java index 213f7fe188..f9d8fca38e 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java @@ -18,8 +18,11 @@ */ package org.sleuthkit.autopsy.geolocation; +import java.awt.Color; +import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -363,21 +366,17 @@ class GeoFilterPanel extends javax.swing.JPanel { * for the numbers of days after the most recent waypoint, not the * current date. * - * @param showAll True if all waypoints should be shown - * @param withoutTimeStamp True to show waypoints without timeStamps, - * this filter is only applicable if - * mostRecentNumDays is true + * @param showAll True if all waypoints should be shown + * @param withoutTimeStamp True to show waypoints without timeStamps, + * this filter is only applicable if mostRecentNumDays is true * @param mostRecentNumDays Show Waypoint for the most recent given - * number of days. This parameter is ignored if - * showAll is true. - * @param dataSources A list of dataSources to filter waypoint - * for. - * @param artifactTypes A list of artifactTypes to filter waypoint - * for. + * number of days. This parameter is ignored if showAll is true. + * @param dataSources A list of dataSources to filter waypoint for. + * @param artifactTypes A list of artifactTypes to filter waypoint for. */ GeoFilter(boolean showAll, boolean withoutTimeStamp, - int mostRecentNumDays, List dataSources, - List artifactTypes) { + int mostRecentNumDays, List dataSources, + List artifactTypes) { this.showAll = showAll; this.showWithoutTimeStamp = withoutTimeStamp; this.mostRecentNumDays = mostRecentNumDays; @@ -420,7 +419,7 @@ class GeoFilterPanel extends javax.swing.JPanel { * all datasources should be include. * * @return A list of dataSources or null if all dataSources should be - * included. + * included. */ List getDataSources() { return Collections.unmodifiableList(dataSources); @@ -439,14 +438,16 @@ class GeoFilterPanel extends javax.swing.JPanel { } /** - * Container for data sources and artifact types to be given as filter options + * Container for data sources and artifact types to be given as filter + * options */ final private class Sources { + final List> dataSources; final Map artifactTypes; private Sources(List> dataSources, - Map artifactTypes) { + Map artifactTypes) { this.dataSources = dataSources; this.artifactTypes = artifactTypes; } @@ -454,9 +455,9 @@ class GeoFilterPanel extends javax.swing.JPanel { /** * SwingWorker for updating the list of valid data sources. - * - * doInBackground creates a list of Pair objects that contain the - * display name of the data source and the data source object. + * + * doInBackground creates a list of Pair objects that contain the display + * name of the data source and the data source object. */ final private class DataSourceUpdater extends SwingWorker { @@ -484,13 +485,13 @@ class GeoFilterPanel extends javax.swing.JPanel { /** * Returns a Map representing the number of sources found for each * artifact type. If no data was found, an empty map is returned. - * + * * @param sleuthkitCase The current sleuthkitCase - * @param dataSource - * + * @param dataSource + * * @return True if the data source as at least one TSK_GPS_XXXX - * - * @throws TskCoreException + * + * @throws TskCoreException */ private Map getGPSDataSources(SleuthkitCase sleuthkitCase, DataSource dataSource) throws TskCoreException { HashMap ret = new HashMap<>(); @@ -503,6 +504,26 @@ class GeoFilterPanel extends javax.swing.JPanel { return ret; } + /** + * Returns a new ImageIcon for the given artifact type ID representing + * the type's waypoint color + * + * @param artifactTypeId The artifact type id + * + * @return the ImageIcon + */ + private ImageIcon getImageIcon(int artifactTypeId) { + Color color = MapWaypoint.getColor(artifactTypeId); + BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); + + Graphics g = img.createGraphics(); + g.setColor(color); + g.fillRect(0, 0, 16, 16); + g.dispose(); + + return new ImageIcon(img); + } + @Override public void done() { Sources sources = null; @@ -523,8 +544,7 @@ class GeoFilterPanel extends javax.swing.JPanel { } for (Map.Entry entry : sources.artifactTypes.entrySet()) { String dispName = entry.getKey().getDisplayName() + " (" + entry.getValue() + ")"; - String iconPath = IconsUtil.getIconFilePath(entry.getKey().getTypeID()); - Icon icon = new ImageIcon(getClass().getResource(iconPath)); + Icon icon = getImageIcon(entry.getKey().getTypeID()); atCheckboxPanel.addElement(dispName, icon, entry.getKey()); } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index 48a0593a95..353915bca7 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -341,12 +341,20 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe return DATE_FORMAT.format(new java.util.Date(timeStamp * 1000)); } + /** + * + * @return the waypoint color that represents the given artifact type id + */ + static Color getColor(int artifactTypeId) { + return artifactTypesToColors.getOrDefault(artifactTypeId, Color.GRAY); + } + /** * * @return the color that this waypoint should be rendered */ Color getColor() { - return artifactTypesToColors.getOrDefault(dataModelWaypoint.getArtifact().getArtifactTypeID(), Color.GRAY); + return getColor(dataModelWaypoint.getArtifact().getArtifactTypeID()); } /** From fdb013d407986fbd49e9014e90f41046155d08dd Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Fri, 10 Apr 2020 12:37:49 -0400 Subject: [PATCH 23/23] 6161: Hightlight color -> yellow --- Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java | 2 +- Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 430d2e58f5..848f561660 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -703,7 +703,7 @@ final public class MapPanel extends javax.swing.JPanel { Color baseColor = waypoint.getColor(); if (waypoint.equals(currentlySelectedWaypoint)) { // Highlight this waypoint since it is selected - return Color.WHITE; + return Color.YELLOW; } else { return baseColor; } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java index 353915bca7..f9e4ed86ee 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java @@ -73,7 +73,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe static { artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID(), Color.BLUE); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID(), Color.RED); - artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID(), Color.YELLOW); + artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID(), Color.CYAN); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID(), Color.GREEN); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID(), Color.ORANGE); artifactTypesToColors.put(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID(), Color.ORANGE);