- added utils to show message / notification in status area

- ingest errors/warnings now show as clickable notifications
This commit is contained in:
adam-m 2013-01-09 16:40:45 -05:00
parent 2f529c1cc0
commit 9b5a84e951
6 changed files with 257 additions and 25 deletions

View File

@ -0,0 +1,203 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

View File

@ -18,6 +18,8 @@
*/ */
package org.sleuthkit.autopsy.ingest; package org.sleuthkit.autopsy.ingest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.List; import java.util.List;
@ -33,6 +35,8 @@ import org.openide.windows.Mode;
import org.openide.windows.TopComponent; import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.Image;
/** /**
@ -45,6 +49,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
private IngestMessageMainPanel messagePanel; private IngestMessageMainPanel messagePanel;
private IngestManager manager; private IngestManager manager;
private static String PREFERRED_ID = "IngestMessageTopComponent"; private static String PREFERRED_ID = "IngestMessageTopComponent";
private ActionListener showIngestInboxAction;
public IngestMessageTopComponent() { public IngestMessageTopComponent() {
initComponents(); initComponents();
@ -54,6 +59,13 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
setToolTipText(NbBundle.getMessage(IngestMessageTopComponent.class, "HINT_IngestMessageTopComponent")); setToolTipText(NbBundle.getMessage(IngestMessageTopComponent.class, "HINT_IngestMessageTopComponent"));
//putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); //putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
showIngestInboxAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
IngestMessagesToolbar.getDefault().showIngestMessages();
}
};
} }
private static synchronized IngestMessageTopComponent getDefault() { private static synchronized IngestMessageTopComponent getDefault() {
@ -80,12 +92,10 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
return PREFERRED_ID; return PREFERRED_ID;
} }
/**
* This method is called from within the constructor to initialize the form.
/** This method is called from within the constructor to * WARNING: Do NOT modify this code. The content of this method is always
* initialize the form. * regenerated by the Form Editor.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/ */
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
@ -204,7 +214,6 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
private void registerListeners() { private void registerListeners() {
//handle case change //handle case change
Case.addPropertyChangeListener(new PropertyChangeListener() { Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) { if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) {
@ -219,8 +228,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
} }
try { try {
manager.stopAll(); manager.stopAll();
} } finally {
finally {
//clear inbox //clear inbox
clearMessages(); clearMessages();
} }
@ -271,9 +279,11 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
} }
} }
if (reportAction == null) if (reportAction == null) {
logger.log(Level.SEVERE, "Could not locate Action: " + reportActionName); 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 @Override
public void displayMessage(IngestMessage ingestMessage) { public void displayMessage(IngestMessage ingestMessage) {
messagePanel.addMessage(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 @Override
@ -292,8 +320,6 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing
return messagePanel.getMessagesCount(); return messagePanel.getMessagesCount();
} }
@Override @Override
public void clearMessages() { public void clearMessages() {
messagePanel.clearMessages(); messagePanel.clearMessages();

View File

@ -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(); IngestMessageTopComponent tc = IngestMessageTopComponent.findInstance();
Mode mode = WindowManager.getDefault().findMode("floatingLeftBottom"); Mode mode = WindowManager.getDefault().findMode("floatingLeftBottom");