From 9b5a84e951b2fb6aa8849c7bf24ca2b09873889f Mon Sep 17 00:00:00 2001 From: adam-m Date: Wed, 9 Jan 2013 16:40:45 -0500 Subject: [PATCH] - added utils to show message / notification in status area - ingest errors/warnings now show as clickable notifications --- .../autopsy/coreutils/MessageNotifyUtil.java | 203 ++++++++++++++++++ .../autopsy/images/error-icon-16.png | Bin 0 -> 775 bytes .../sleuthkit/autopsy/images/info-icon-16.png | Bin 0 -> 791 bytes .../autopsy/images/warning-icon-16.png | Bin 0 -> 867 bytes .../ingest/IngestMessageTopComponent.java | 74 ++++--- .../autopsy/ingest/IngestMessagesToolbar.java | 5 +- 6 files changed, 257 insertions(+), 25 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/coreutils/MessageNotifyUtil.java create mode 100644 Core/src/org/sleuthkit/autopsy/images/error-icon-16.png create mode 100644 Core/src/org/sleuthkit/autopsy/images/info-icon-16.png create mode 100644 Core/src/org/sleuthkit/autopsy/images/warning-icon-16.png diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/MessageNotifyUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/MessageNotifyUtil.java new file mode 100644 index 0000000000..0b5c96993d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/coreutils/MessageNotifyUtil.java @@ -0,0 +1,203 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.coreutils; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URL; +import java.util.logging.Level; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.awt.NotificationDisplayer; +import org.openide.util.ImageUtilities; + +/** + * Utility for displaying messages and notifications in status area. Wraps + * around NB RCP NotificationDisplayer. + * + * Messages can optionally contain click-able Actions. + * + * Based on: + * http://qbeukes.blogspot.com/2009/11/netbeans-platform-notifications.html + * + * @license Apache License 2.0 + */ +public class MessageNotifyUtil { + + private MessageNotifyUtil() { + } + + public enum MessageType { + + INFO(NotifyDescriptor.INFORMATION_MESSAGE, "info-icon-16.png"), + ERROR(NotifyDescriptor.ERROR_MESSAGE, "error-icon-16.png"), + WARNING(NotifyDescriptor.WARNING_MESSAGE, "warning-icon-16.png"); + private int notifyDescriptorType; + private Icon icon; + + private MessageType(int notifyDescriptorType, String resourceName) { + this.notifyDescriptorType = notifyDescriptorType; + if (resourceName == null) { + icon = new ImageIcon(); + } else { + icon = loadIcon(resourceName); + } + } + + private static Icon loadIcon(String resourceName) { + Icon icon = ImageUtilities.loadImageIcon("org/sleuthkit/autopsy/images/" + resourceName, false); + if (icon == null) { + Logger logger = Logger.getLogger(org.sleuthkit.autopsy.coreutils.MessageNotifyUtil.MessageType.class.getName()); + logger.log(Level.SEVERE, "Failed to load icon resource: " + resourceName + ". Using blank image."); + icon = new ImageIcon(); + } + return icon; + } + + int getNotifyDescriptorType() { + return notifyDescriptorType; + } + + Icon getIcon() { + return icon; + } + } + + /** + * Utility to display messages + */ + public static class Message { + + private Message() { + } + + /** + * @return The dialog displayer used to show message boxes + */ + public static DialogDisplayer getDialogDisplayer() { + return DialogDisplayer.getDefault(); + } + + /** + * Show a message of the specified type + * + * @param message message to show + * @param messageType message type to show + */ + public static void show(String message, MessageType messageType) { + getDialogDisplayer().notify(new NotifyDescriptor.Message(message, + messageType.getNotifyDescriptorType())); + } + + /** + * Show an information dialog + * + * @param message message to show + */ + public static void info(String message) { + show(message, MessageType.INFO); + } + + /** + * Show an error dialog + * + * @param message message to shpw + */ + public static void error(String message) { + show(message, MessageType.ERROR); + } + + /** + * Show an warning dialog + * + * @param message message to show + */ + public static void warn(String message) { + show(message, MessageType.WARNING); + } + } + + /** + * Utility to display notifications with baloons + */ + public static class Notify { + + private Notify() { + } + + /** + * Show message with the specified type and action listener + */ + public static void show(String title, String message, MessageType type, ActionListener actionListener) { + NotificationDisplayer.getDefault().notify(title, type.getIcon(), message, actionListener); + } + + /** + * Show message with the specified type and a default action which + * displays the message using MessageNotifyUtil.Message with the same + * message type + * + * @param title message title + * @param message message text + * @param type type of the message + */ + public static void show(String title, final String message, final MessageType type) { + ActionListener actionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MessageNotifyUtil.Message.show(message, type); + } + }; + + show(title, message, type, actionListener); + } + + /** + * Show an information notification + * + * @param title message title + * @param message message text + */ + public static void info(String title, String message) { + show(title, message, MessageType.INFO); + } + + /** + * Show an error notification + * + * @param title message title + * @param message message text + */ + public static void error(String title, String message) { + show(title, message, MessageType.ERROR); + } + + /** + * Show an warning notification + * + * @param title message title + * @param message message text + */ + public static void warn(String title, String message) { + show(title, message, MessageType.WARNING); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/images/error-icon-16.png b/Core/src/org/sleuthkit/autopsy/images/error-icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..54ef8cefacf8ad076129c58c3d94c5dad2c9eb76 GIT binary patch literal 775 zcmV+i1Ni)jP)oU|iOS6an-!uu1g7ANA8rOQ&dV_dyCwcpGJ#_; z^tNSEx^f<*ra?Fck=UPSFbE^#aCC~HeyLD!K9j%+?koAMt1OX>QDK!Ji}0s}Al^dQ z24C$GEj}egZ$Cm~fZL<6K2ET?H4|6;5{L=F`U12N|Fw{`G?)XEg1RFlCnIc8h0xJ1gX@pyj6Fq!{;dB^Eg>!zH!GV1AL$gszrlR6K&vi26 zZZEbuB_@gdB*1S539MU-<{js|COgf5&S`XY(23qyAOw9RCMFh}S47Su4^~Hkd5`$U z__Vy76amLgHp{IUa3hSNcH}aCq6mi?kgw4MfxW(-%=UI+O>8+{iNCoS|EW{veOmmE zv~VrLgj$eF&#n1v(!DaQNyyl?jl9lI6Fm9+DavYPW@(v8GO>L-fvzsbq=i25mMAyP zHC~&8t3t}xgv4G~M{!37pZlKR-B2Y{wJ_Ixo2;@$j8s=M-QA5R1w7KnSwq$sS7V7y zgjB>@n^d5GR)m)=MH?6(J(v(gC_SBsvyhD85#CAW5lME&z%7!l`X%N36>0Py%VuGk z=-whkTJ%p5O-bYj@lgR^HhB38*8G<8Ps??taA}X7jTIJ@Awr3J{4s?D^j*%r7>3Kh zB`V+h_hU-7HQ9=tWfoS8;EHtt`(k*940^vMp7Vp`;2&@^6h|grps@e|002ovPDHLk FV1k#xZCU^T literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/info-icon-16.png b/Core/src/org/sleuthkit/autopsy/images/info-icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e499782c6e78fc6b23d743f4b29baa398699ce GIT binary patch literal 791 zcmV+y1L*vTP)vORuoxkyWZB_J$pHqndVHnyVeiGe9ZsPH}lW;4TAq;4;V8WxxDQq zV9Cw_gaABKQ~2xfAOsff()_E$Vw8Y0k;&Yl-F>8H&5kmpGZ}&7wE%>G5{ZK34?^_A zAd!b2^pL>Z30l99NMPY?1p~&~^9827T+s3wAc{f<1|lmA108Zi1Yu?tLVY(UuxFx# z?(;GNlwxzI*SD3M3N`^?1&~GqNXtXz#tg>Z_hlZGpa8NjKnZ0C|C|ATZ_5i3@a$6w zYD|u1XGUce-HZY8JRpvPt!4wb>WUaaP4_5#oD%?xB1ES>fN4v@$Quw|-l|2&WOJ=+ zzE`bD*3+wSv8GaZ4({yFXZX~!N$^XUVIs*8`92Mb5Qe3$i!P)uuJBqLFPmAPWVIXz z3oUGZH0E8kE-m^%nqLCHyTgl8%Ik63fkuQyiM{wr7 z7GpU~{U9&-!T?Fn?#BLK6)RS@>Nac}NOPRA z6NLk{9iSG@%}8R&Z;RnS{-AG!BOwS5b&kv4$4QYPf4E10TNzTzw_(F;@>~P VS_#VW`A`4=002ovPDHLkV1ju1bi)7u literal 0 HcmV?d00001 diff --git a/Core/src/org/sleuthkit/autopsy/images/warning-icon-16.png b/Core/src/org/sleuthkit/autopsy/images/warning-icon-16.png new file mode 100644 index 0000000000000000000000000000000000000000..42a1625a37d853b12a1bc5e88af7a0f5bbb0ac54 GIT binary patch literal 867 zcmV-p1DyPcP)NfJ$d~M{HdzUYdPMx(Yj{5?1jX{tUm@WI30bXSqm3$gr;R%L+ z%n$$cr*&otU`~$d^O_;aYPbtZLkfz~NeWh@lAC~_s4!RVB!C6aeuipc5~b`TSh><- zZ~ttJ^`xXNzn|mdqM<{N#Gy8IB4ox1kc2&V9g?EKY$Xd$7Eb9Y*?NGoHG`mB#@EM+ zz3lT1Y;brFyCj(k8e3unX@}O-Ms-M_{OT@5RYSPrGq{ymIEyo+U>bHl2XC>8Ll^Dc z?9(0$p8gh>L|ud#Gtd}ohTa^38g4~?`WY#Z5lyWp|9Mi7MXi{FU9jOSI5;}u?qKWQQhHbKg$m8!58JP3Y(?L$uQQW3*rr`W6* za18=ONS6pCK_ghH7(kK*#M))}UI4e|qh{ApcQ~wqU)XWpZC`%I9ewP|{x5O3TIKZa z46-UhCD84wHOLCE`5O~;Hy{XyUk7C7//GEN-BEGIN:initComponents private void initComponents() { @@ -124,11 +134,11 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing super.componentClosed(); /* - Mode mode = WindowManager.getDefault().findMode("dockedBottom"); - if (mode != null) { - mode.dockInto(this); - this.open(); - } + Mode mode = WindowManager.getDefault().findMode("dockedBottom"); + if (mode != null) { + mode.dockInto(this); + this.open(); + } * */ //this.close(); @@ -204,7 +214,6 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing private void registerListeners() { //handle case change Case.addPropertyChangeListener(new PropertyChangeListener() { - @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) { @@ -219,8 +228,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing } try { manager.stopAll(); - } - finally { + } finally { //clear inbox clearMessages(); } @@ -257,7 +265,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing final String reportActionName = "org.sleuthkit.autopsy.report.ReportAction"; Action reportAction = null; - + //find action by name from action lookup, without introducing cyclic dependency if (choice == JOptionPane.NO_OPTION) { List actions = Utilities.actionsForPath("Toolbars/File"); @@ -270,11 +278,13 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing } } } - - if (reportAction == null) + + if (reportAction == null) { logger.log(Level.SEVERE, "Could not locate Action: " + reportActionName); - else reportAction.actionPerformed(null); - + } else { + reportAction.actionPerformed(null); + } + } } @@ -285,6 +295,24 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing @Override public void displayMessage(IngestMessage ingestMessage) { messagePanel.addMessage(ingestMessage); + + + //post special messages to notification area + MessageType ingestMessageType = ingestMessage.getMessageType(); + if (ingestMessageType.equals(MessageType.ERROR) + || ingestMessageType.equals(MessageType.WARNING)) { + MessageNotifyUtil.MessageType notifyMessageType = + ingestMessageType.equals(MessageType.ERROR) + ? MessageNotifyUtil.MessageType.ERROR + : MessageNotifyUtil.MessageType.WARNING; + + String details = ingestMessage.getDetails(); + if (details == null) { + details = ""; + } + MessageNotifyUtil.Notify.show(ingestMessage.getSubject(), details, + notifyMessageType, showIngestInboxAction); + } } @Override @@ -292,8 +320,6 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing return messagePanel.getMessagesCount(); } - - @Override public void clearMessages() { messagePanel.clearMessages(); @@ -302,9 +328,9 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing @Override public void displayIngestDialog(final Image image) { /* - final IngestDialog ingestDialog = new IngestDialog(); - ingestDialog.setImage(image); - ingestDialog.display(); + final IngestDialog ingestDialog = new IngestDialog(); + ingestDialog.setImage(image); + ingestDialog.display(); */ } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java index ef4a89777d..51167f8ef9 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestMessagesToolbar.java @@ -130,7 +130,10 @@ public class IngestMessagesToolbar extends javax.swing.JPanel { }); } - private void showIngestMessages() { + /** + * Pop up and show ingest messages window + */ + void showIngestMessages() { IngestMessageTopComponent tc = IngestMessageTopComponent.findInstance(); Mode mode = WindowManager.getDefault().findMode("floatingLeftBottom");